Merge "Handle the case when Telecom rejects an incoming call"
diff --git a/sip/src/com/android/services/telephony/sip/SipAccountRegistry.java b/sip/src/com/android/services/telephony/sip/SipAccountRegistry.java
index ec77ff1..1cf7f4b 100644
--- a/sip/src/com/android/services/telephony/sip/SipAccountRegistry.java
+++ b/sip/src/com/android/services/telephony/sip/SipAccountRegistry.java
@@ -126,7 +126,7 @@
* @param context The context.
*/
void verifyAndPurgeInvalidPhoneAccounts(Context context) {
- TelecomManager telecomManager = TelecomManager.from(context);
+ TelecomManager telecomManager = context.getSystemService(TelecomManager.class);
SipProfileDb profileDb = new SipProfileDb(context);
List<PhoneAccountHandle> accountHandles = telecomManager.getPhoneAccountsSupportingScheme(
PhoneAccount.SCHEME_SIP);
@@ -188,7 +188,8 @@
// Un-register its PhoneAccount.
PhoneAccountHandle handle = SipUtil.createAccountHandle(context, sipProfileName);
- TelecomManager.from(context).unregisterPhoneAccount(handle);
+ TelecomManager tm = context.getSystemService(TelecomManager.class);
+ tm.unregisterPhoneAccount(handle);
}
/**
@@ -235,7 +236,7 @@
private void startSipProfiles(Context context, String sipProfileName, boolean enableProfile) {
final SipPreferences sipPreferences = new SipPreferences(context);
boolean isReceivingCalls = sipPreferences.isReceivingCallsEnabled();
- TelecomManager telecomManager = TelecomManager.from(context);
+ TelecomManager telecomManager = context.getSystemService(TelecomManager.class);
SipManager sipManager = SipManager.newInstance(context);
SipProfileDb profileDb = new SipProfileDb(context);
List<SipProfile> sipProfileList = profileDb.retrieveSipProfileList();
diff --git a/sip/src/com/android/services/telephony/sip/SipIncomingCallReceiver.java b/sip/src/com/android/services/telephony/sip/SipIncomingCallReceiver.java
index 19f5882..3212c00 100644
--- a/sip/src/com/android/services/telephony/sip/SipIncomingCallReceiver.java
+++ b/sip/src/com/android/services/telephony/sip/SipIncomingCallReceiver.java
@@ -73,7 +73,7 @@
if (accountHandle != null) {
Bundle extras = new Bundle();
extras.putParcelable(SipUtil.EXTRA_INCOMING_CALL_INTENT, intent);
- TelecomManager tm = TelecomManager.from(context);
+ TelecomManager tm = context.getSystemService(TelecomManager.class);
PhoneAccount phoneAccount = tm.getPhoneAccount(accountHandle);
if (phoneAccount != null && phoneAccount.isEnabled()) {
tm.addNewIncomingCall(accountHandle, extras);
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
index 17a1734..3858595 100644
--- a/src/com/android/phone/CallFeaturesSetting.java
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -214,7 +214,7 @@
mSubscriptionInfoHelper.setActionBarTitle(
getActionBar(), getResources(), R.string.call_settings_with_label);
mPhone = mSubscriptionInfoHelper.getPhone();
- mTelecomManager = TelecomManager.from(this);
+ mTelecomManager = getSystemService(TelecomManager.class);
}
private void updateImsManager(Phone phone) {
diff --git a/src/com/android/phone/ImsRcsController.java b/src/com/android/phone/ImsRcsController.java
new file mode 100644
index 0000000..d1ff56f
--- /dev/null
+++ b/src/com/android/phone/ImsRcsController.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone;
+
+import android.content.Context;
+import android.net.Uri;
+import android.os.ServiceManager;
+import android.telephony.ims.aidl.IImsCapabilityCallback;
+import android.telephony.ims.aidl.IImsRcsController;
+import android.telephony.ims.aidl.IRcsUceControllerCallback;
+import android.telephony.ims.feature.RcsFeature;
+import android.util.Log;
+
+import java.util.List;
+
+/**
+ * Implementation of the IImsRcsController interface.
+ */
+public class ImsRcsController extends IImsRcsController.Stub {
+ private static final String TAG = "ImsRcsController";
+
+ /** The singleton instance. */
+ private static ImsRcsController sInstance;
+
+ private PhoneGlobals mApp;
+
+ /**
+ * Initialize the singleton ImsRcsController instance.
+ * This is only done once, at startup, from PhoneApp.onCreate().
+ */
+ static ImsRcsController init(PhoneGlobals app) {
+ synchronized (ImsRcsController.class) {
+ if (sInstance == null) {
+ sInstance = new ImsRcsController(app);
+ } else {
+ Log.wtf(TAG, "init() called multiple times! sInstance = " + sInstance);
+ }
+ return sInstance;
+ }
+ }
+
+ /** Private constructor; @see init() */
+ private ImsRcsController(PhoneGlobals app) {
+ Log.i(TAG, "ImsRcsController");
+ mApp = app;
+ ServiceManager.addService(Context.TELEPHONY_IMS_SERVICE, this);
+ }
+
+ @Override
+ public void registerRcsAvailabilityCallback(IImsCapabilityCallback c) {
+ enforceReadPrivilegedPermission("registerRcsAvailabilityCallback");
+ }
+
+ @Override
+ public void unregisterRcsAvailabilityCallback(IImsCapabilityCallback c) {
+ enforceReadPrivilegedPermission("unregisterRcsAvailabilityCallback");
+ }
+
+ @Override
+ public boolean isCapable(int subId,
+ @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability) {
+ enforceReadPrivilegedPermission("isCapable");
+ return false;
+ }
+
+ @Override
+ public boolean isAvailable(int subId,
+ @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability) {
+ enforceReadPrivilegedPermission("isAvailable");
+ return false;
+ }
+
+ @Override
+ public void requestCapabilities(int subId, List<Uri> contactNumbers,
+ IRcsUceControllerCallback c) {
+ enforceReadPrivilegedPermission("requestCapabilities");
+ }
+
+ @Override
+ public int getUcePublishState(int subId) {
+ enforceReadPrivilegedPermission("getUcePublishState");
+ return -1;
+ }
+
+ @Override
+ public boolean isUceSettingEnabled(int subId) {
+ enforceReadPrivilegedPermission("isUceSettingEnabled");
+ return false;
+ }
+
+ @Override
+ public void setUceSettingEnabled(int subId, boolean isEnabled) {
+ enforceModifyPermission();
+ }
+
+ /**
+ * Make sure either called from same process as self (phone) or IPC caller has read privilege.
+ *
+ * @throws SecurityException if the caller does not have the required permission
+ */
+ private void enforceReadPrivilegedPermission(String message) {
+ mApp.enforceCallingOrSelfPermission(
+ android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, message);
+ }
+
+ /**
+ * Make sure the caller has the MODIFY_PHONE_STATE permission.
+ *
+ * @throws SecurityException if the caller does not have the required permission
+ */
+ private void enforceModifyPermission() {
+ mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
+ }
+}
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index 475cc1f..d35d9a6 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -42,7 +42,6 @@
import android.preference.PreferenceManager;
import android.provider.ContactsContract.PhoneLookup;
import android.provider.Settings;
-import android.telecom.DefaultDialerManager;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
@@ -164,7 +163,7 @@
(StatusBarManager) app.getSystemService(Context.STATUS_BAR_SERVICE);
mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
mSubscriptionManager = SubscriptionManager.from(mContext);
- mTelecomManager = TelecomManager.from(mContext);
+ mTelecomManager = app.getSystemService(TelecomManager.class);
mTelephonyManager = (TelephonyManager) app.getSystemService(Context.TELEPHONY_SERVICE);
}
@@ -472,8 +471,8 @@
}
private Intent getShowVoicemailIntentForDefaultDialer(UserHandle userHandle) {
- String dialerPackage = DefaultDialerManager
- .getDefaultDialerApplication(mContext, userHandle.getIdentifier());
+ String dialerPackage = mContext.getSystemService(TelecomManager.class)
+ .getDefaultDialerPackage(userHandle.getIdentifier());
return new Intent(TelephonyManager.ACTION_SHOW_VOICEMAIL_NOTIFICATION)
.setPackage(dialerPackage);
}
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 06ae81c..b9c6728 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -147,6 +147,7 @@
CallerInfoCache callerInfoCache;
NotificationMgr notificationMgr;
public PhoneInterfaceManager phoneMgr;
+ public ImsRcsController imsRcsController;
CarrierConfigLoader configLoader;
private Phone phoneInEcm;
@@ -353,6 +354,8 @@
phoneMgr = PhoneInterfaceManager.init(this);
+ imsRcsController = ImsRcsController.init(this);
+
configLoader = CarrierConfigLoader.init(this);
// Create the CallNotifier singleton, which handles
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 0940954..3ddb267 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -2637,7 +2637,8 @@
@Override
public Bundle getVisualVoicemailSettings(String callingPackage, int subId) {
mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
- String systemDialer = TelecomManager.from(mApp).getSystemDialerPackage();
+ TelecomManager tm = mApp.getSystemService(TelecomManager.class);
+ String systemDialer = tm.getSystemDialerPackage();
if (!TextUtils.equals(callingPackage, systemDialer)) {
throw new SecurityException("caller must be system dialer");
}
@@ -2863,8 +2864,8 @@
public void sendDialerSpecialCode(String callingPackage, String inputCode) {
final Phone defaultPhone = getDefaultPhone();
mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
- String defaultDialer = TelecomManager.from(defaultPhone.getContext())
- .getDefaultDialerPackage();
+ TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
+ String defaultDialer = tm.getDefaultDialerPackage();
if (!TextUtils.equals(callingPackage, defaultDialer)) {
TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
getDefaultSubscription(), "sendDialerSpecialCode");
@@ -4899,7 +4900,7 @@
* @hide
*/
@Override
- public boolean getTetherApnRequiredForSubscriber(int subId) {
+ public boolean isTetherApnRequiredForSubscriber(int subId) {
enforceModifyPermission();
final long identity = Binder.clearCallingIdentity();
final Phone phone = getPhone(subId);
@@ -5032,6 +5033,52 @@
}
}
+ private int getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim,
+ Phone phone) {
+ //load access rules from carrier configs, and check those as well: b/139133814
+ SubscriptionController subController = SubscriptionController.getInstance();
+ if (privilegeFromSim == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
+ || subController == null) return privilegeFromSim;
+
+ int uid = Binder.getCallingUid();
+ PackageManager pkgMgr = phone.getContext().getPackageManager();
+ String[] packages = pkgMgr.getPackagesForUid(uid);
+
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ SubscriptionInfo subInfo = subController.getSubscriptionInfo(phone.getSubId());
+ SubscriptionManager subManager = (SubscriptionManager)
+ phone.getContext().getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+ for (String pkg : packages) {
+ if (subManager.canManageSubscription(subInfo, pkg)) {
+ return TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
+ }
+ }
+ return privilegeFromSim;
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ private int getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim, Phone phone,
+ String pkgName) {
+ //load access rules from carrier configs, and check those as well: b/139133814
+ SubscriptionController subController = SubscriptionController.getInstance();
+ if (privilegeFromSim == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
+ || subController == null) return privilegeFromSim;
+
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ SubscriptionInfo subInfo = subController.getSubscriptionInfo(phone.getSubId());
+ SubscriptionManager subManager = (SubscriptionManager)
+ phone.getContext().getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+ return subManager.canManageSubscription(subInfo, pkgName)
+ ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS : privilegeFromSim;
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
@Override
public int getCarrierPrivilegeStatus(int subId) {
final Phone phone = getPhone(subId);
@@ -5044,8 +5091,10 @@
loge("getCarrierPrivilegeStatus: No UICC");
return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
}
- return card.getCarrierPrivilegeStatusForCurrentTransaction(
- phone.getContext().getPackageManager());
+
+ return getCarrierPrivilegeStatusFromCarrierConfigRules(
+ card.getCarrierPrivilegeStatusForCurrentTransaction(
+ phone.getContext().getPackageManager()), phone);
}
@Override
@@ -5061,7 +5110,9 @@
loge("getCarrierPrivilegeStatusForUid: No UICC");
return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
}
- return profile.getCarrierPrivilegeStatusForUid(phone.getContext().getPackageManager(), uid);
+ return getCarrierPrivilegeStatusFromCarrierConfigRules(
+ profile.getCarrierPrivilegeStatusForUid(
+ phone.getContext().getPackageManager(), uid), phone);
}
@Override
@@ -5076,8 +5127,9 @@
loge("checkCarrierPrivilegesForPackage: No UICC on subId " + subId);
return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
}
-
- return card.getCarrierPrivilegeStatus(mApp.getPackageManager(), pkgName);
+ return getCarrierPrivilegeStatusFromCarrierConfigRules(
+ card.getCarrierPrivilegeStatus(mApp.getPackageManager(), pkgName),
+ getPhone(phoneId), pkgName);
}
@Override
@@ -5092,7 +5144,9 @@
continue;
}
- result = card.getCarrierPrivilegeStatus(mApp.getPackageManager(), pkgName);
+ result = getCarrierPrivilegeStatusFromCarrierConfigRules(
+ card.getCarrierPrivilegeStatus(mApp.getPackageManager(), pkgName),
+ getPhone(i), pkgName);
if (result == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
break;
}
@@ -5127,9 +5181,9 @@
if (packages == null) {
// Only check packages in user 0 for now
packages = pm.getInstalledPackagesAsUser(
- PackageManager.MATCH_DISABLED_COMPONENTS
- | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
- | PackageManager.GET_SIGNATURES, UserHandle.USER_SYSTEM);
+ PackageManager.MATCH_DISABLED_COMPONENTS
+ | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+ | PackageManager.GET_SIGNATURES, UserHandle.USER_SYSTEM);
}
for (int p = packages.size() - 1; p >= 0; p--) {
PackageInfo pkgInfo = packages.get(p);
@@ -5563,7 +5617,7 @@
@Override
public boolean isTtyModeSupported() {
- TelecomManager telecomManager = TelecomManager.from(mApp);
+ TelecomManager telecomManager = mApp.getSystemService(TelecomManager.class);
return telecomManager.isTtySupported();
}
@@ -6022,8 +6076,8 @@
PhoneAccountHandle phoneAccountHandle, Uri uri) {
final Phone defaultPhone = getDefaultPhone();
mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
- if (!TextUtils.equals(callingPackage,
- TelecomManager.from(defaultPhone.getContext()).getDefaultDialerPackage())) {
+ TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
+ if (!TextUtils.equals(callingPackage, tm.getDefaultDialerPackage())) {
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
"setVoicemailRingtoneUri");
@@ -6079,8 +6133,8 @@
PhoneAccountHandle phoneAccountHandle, boolean enabled) {
final Phone defaultPhone = getDefaultPhone();
mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
- if (!TextUtils.equals(callingPackage,
- TelecomManager.from(defaultPhone.getContext()).getDefaultDialerPackage())) {
+ TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
+ if (!TextUtils.equals(callingPackage, tm.getDefaultDialerPackage())) {
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
"setVoicemailVibrationEnabled");
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index 6c3f0bf..9835ba1 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -31,6 +31,7 @@
import android.telecom.VideoProfile;
import android.telephony.CarrierConfigManager;
import android.telephony.PhoneNumberUtils;
+import android.telephony.Rlog;
import android.telephony.SubscriptionManager;
import android.text.TextUtils;
import android.util.Log;
@@ -43,10 +44,7 @@
import android.widget.Toast;
import com.android.internal.telephony.Call;
-import com.android.internal.telephony.CallManager;
import com.android.internal.telephony.CallStateException;
-import android.telephony.CallerInfo;
-import android.telephony.CallerInfoAsyncQuery;
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.MmiCode;
@@ -54,10 +52,8 @@
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.TelephonyCapabilities;
-import com.android.phone.CallGatewayManager.RawGatewayInfo;
import com.android.phone.settings.SuppServicesUiUtil;
-import java.util.Arrays;
import java.util.List;
/**
@@ -131,79 +127,35 @@
}
/**
- * @see placeCall below
- */
- public static int placeCall(Context context, Phone phone, String number, Uri contactRef,
- boolean isEmergencyCall) {
- return placeCall(context, phone, number, contactRef, isEmergencyCall,
- CallGatewayManager.EMPTY_INFO, null);
- }
-
- /**
* Dial the number using the phone passed in.
*
- * If the connection is establised, this method issues a sync call
- * that may block to query the caller info.
- * TODO: Change the logic to use the async query.
- *
* @param context To perform the CallerInfo query.
* @param phone the Phone object.
* @param number to be dialed as requested by the user. This is
* NOT the phone number to connect to. It is used only to build the
* call card and to update the call log. See above for restrictions.
- * @param contactRef that triggered the call. Typically a 'tel:'
- * uri but can also be a 'content://contacts' one.
- * @param isEmergencyCall indicates that whether or not this is an
- * emergency call
- * @param gatewayUri Is the address used to setup the connection, null
- * if not using a gateway
- * @param callGateway Class for setting gateway data on a successful call.
*
* @return either CALL_STATUS_DIALED or CALL_STATUS_FAILED
*/
- public static int placeCall(Context context, Phone phone, String number, Uri contactRef,
- boolean isEmergencyCall, RawGatewayInfo gatewayInfo, CallGatewayManager callGateway) {
- final Uri gatewayUri = gatewayInfo.gatewayUri;
+ public static int placeOtaspCall(Context context, Phone phone, String number) {
+ final Uri gatewayUri = null;
if (VDBG) {
log("placeCall()... number: '" + number + "'"
- + ", GW:'" + gatewayUri + "'"
- + ", contactRef:" + contactRef
- + ", isEmergencyCall: " + isEmergencyCall);
+ + ", GW:'" + gatewayUri + "'");
} else {
log("placeCall()... number: " + toLogSafePhoneNumber(number)
- + ", GW: " + (gatewayUri != null ? "non-null" : "null")
- + ", emergency? " + isEmergencyCall);
+ + ", GW: " + (gatewayUri != null ? "non-null" : "null"));
}
final PhoneGlobals app = PhoneGlobals.getInstance();
boolean useGateway = false;
- if (null != gatewayUri &&
- !isEmergencyCall &&
- PhoneUtils.isRoutableViaGateway(number)) { // Filter out MMI, OTA and other codes.
- useGateway = true;
- }
+ Uri contactRef = null;
int status = CALL_STATUS_DIALED;
Connection connection;
String numberToDial;
- if (useGateway) {
- // TODO: 'tel' should be a constant defined in framework base
- // somewhere (it is in webkit.)
- if (null == gatewayUri || !PhoneAccount.SCHEME_TEL.equals(gatewayUri.getScheme())) {
- Log.e(LOG_TAG, "Unsupported URL:" + gatewayUri);
- return CALL_STATUS_FAILED;
- }
-
- // We can use getSchemeSpecificPart because we don't allow #
- // in the gateway numbers (treated a fragment delim.) However
- // if we allow more complex gateway numbers sequence (with
- // passwords or whatnot) that use #, this may break.
- // TODO: Need to support MMI codes.
- numberToDial = gatewayUri.getSchemeSpecificPart();
- } else {
- numberToDial = number;
- }
+ numberToDial = number;
try {
connection = app.mCM.dial(phone, numberToDial, VideoProfile.STATE_AUDIO_ONLY);
@@ -228,33 +180,6 @@
if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
updateCdmaCallStateOnNewOutgoingCall(app, connection);
}
-
- if (gatewayUri == null) {
- // phone.dial() succeeded: we're now in a normal phone call.
- // attach the URI to the CallerInfo Object if it is there,
- // otherwise just attach the Uri Reference.
- // if the uri does not have a "content" scheme, then we treat
- // it as if it does NOT have a unique reference.
- String content = context.getContentResolver().SCHEME_CONTENT;
- if ((contactRef != null) && (contactRef.getScheme().equals(content))) {
- Object userDataObject = connection.getUserData();
- if (userDataObject == null) {
- connection.setUserData(contactRef);
- } else {
- // TODO: This branch is dead code, we have
- // just created the connection which has
- // no user data (null) by default.
- if (userDataObject instanceof CallerInfo) {
- ((CallerInfo) userDataObject).contactRefUri = contactRef;
- } else {
- ((CallerInfoToken) userDataObject).currentInfo.contactRefUri =
- contactRef;
- }
- }
- }
- }
-
- startGetCallerInfo(context, connection, null, null, gatewayInfo);
}
return status;
@@ -299,7 +224,7 @@
MmiCode mmiCode,
Message buttonCallbackMessage,
Dialog previousAlert) {
- log("displayMMIInitiate: " + android.telecom.Log.pii(mmiCode.toString()));
+ log("displayMMIInitiate: " + Rlog.pii(LOG_TAG, mmiCode.toString()));
if (previousAlert != null) {
previousAlert.dismiss();
}
@@ -662,533 +587,12 @@
return canceled;
}
- /**
- * Returns the caller-id info corresponding to the specified Connection.
- * (This is just a simple wrapper around CallerInfo.getCallerInfo(): we
- * extract a phone number from the specified Connection, and feed that
- * number into CallerInfo.getCallerInfo().)
- *
- * The returned CallerInfo may be null in certain error cases, like if the
- * specified Connection was null, or if we weren't able to get a valid
- * phone number from the Connection.
- *
- * Finally, if the getCallerInfo() call did succeed, we save the resulting
- * CallerInfo object in the "userData" field of the Connection.
- *
- * NOTE: This API should be avoided, with preference given to the
- * asynchronous startGetCallerInfo API.
- */
- static CallerInfo getCallerInfo(Context context, Connection c) {
- CallerInfo info = null;
-
- if (c != null) {
- //See if there is a URI attached. If there is, this means
- //that there is no CallerInfo queried yet, so we'll need to
- //replace the URI with a full CallerInfo object.
- Object userDataObject = c.getUserData();
- if (userDataObject instanceof Uri) {
- info = CallerInfo.getCallerInfo(context, (Uri) userDataObject);
- if (info != null) {
- c.setUserData(info);
- }
- } else {
- if (userDataObject instanceof CallerInfoToken) {
- //temporary result, while query is running
- info = ((CallerInfoToken) userDataObject).currentInfo;
- } else {
- //final query result
- info = (CallerInfo) userDataObject;
- }
- if (info == null) {
- // No URI, or Existing CallerInfo, so we'll have to make do with
- // querying a new CallerInfo using the connection's phone number.
- String number = c.getAddress();
-
- if (DBG) log("getCallerInfo: number = " + toLogSafePhoneNumber(number));
-
- if (!TextUtils.isEmpty(number)) {
- info = CallerInfo.getCallerInfo(context, number);
- if (info != null) {
- c.setUserData(info);
- }
- }
- }
- }
- }
- return info;
- }
-
- /**
- * Class returned by the startGetCallerInfo call to package a temporary
- * CallerInfo Object, to be superceded by the CallerInfo Object passed
- * into the listener when the query with token mAsyncQueryToken is complete.
- */
- public static class CallerInfoToken {
- /**indicates that there will no longer be updates to this request.*/
- public boolean isFinal;
-
- public CallerInfo currentInfo;
- public CallerInfoAsyncQuery asyncQuery;
- }
-
- /**
- * place a temporary callerinfo object in the hands of the caller and notify
- * caller when the actual query is done.
- */
- static CallerInfoToken startGetCallerInfo(Context context, Connection c,
- CallerInfoAsyncQuery.OnQueryCompleteListener listener, Object cookie,
- RawGatewayInfo info) {
- CallerInfoToken cit;
-
- if (c == null) {
- //TODO: perhaps throw an exception here.
- cit = new CallerInfoToken();
- cit.asyncQuery = null;
- return cit;
- }
-
- Object userDataObject = c.getUserData();
-
- // There are now 3 states for the Connection's userData object:
- //
- // (1) Uri - query has not been executed yet
- //
- // (2) CallerInfoToken - query is executing, but has not completed.
- //
- // (3) CallerInfo - query has executed.
- //
- // In each case we have slightly different behaviour:
- // 1. If the query has not been executed yet (Uri or null), we start
- // query execution asynchronously, and note it by attaching a
- // CallerInfoToken as the userData.
- // 2. If the query is executing (CallerInfoToken), we've essentially
- // reached a state where we've received multiple requests for the
- // same callerInfo. That means that once the query is complete,
- // we'll need to execute the additional listener requested.
- // 3. If the query has already been executed (CallerInfo), we just
- // return the CallerInfo object as expected.
- // 4. Regarding isFinal - there are cases where the CallerInfo object
- // will not be attached, like when the number is empty (caller id
- // blocking). This flag is used to indicate that the
- // CallerInfoToken object is going to be permanent since no
- // query results will be returned. In the case where a query
- // has been completed, this flag is used to indicate to the caller
- // that the data will not be updated since it is valid.
- //
- // Note: For the case where a number is NOT retrievable, we leave
- // the CallerInfo as null in the CallerInfoToken. This is
- // something of a departure from the original code, since the old
- // code manufactured a CallerInfo object regardless of the query
- // outcome. From now on, we will append an empty CallerInfo
- // object, to mirror previous behaviour, and to avoid Null Pointer
- // Exceptions.
-
- if (userDataObject instanceof Uri) {
- // State (1): query has not been executed yet
-
- //create a dummy callerinfo, populate with what we know from URI.
- cit = new CallerInfoToken();
- cit.currentInfo = new CallerInfo();
- cit.asyncQuery = CallerInfoAsyncQuery.startQuery(QUERY_TOKEN, context,
- (Uri) userDataObject, sCallerInfoQueryListener, c);
- cit.asyncQuery.addQueryListener(QUERY_TOKEN, listener, cookie);
- cit.isFinal = false;
-
- c.setUserData(cit);
-
- if (DBG) log("startGetCallerInfo: query based on Uri: " + userDataObject);
-
- } else if (userDataObject == null) {
- // No URI, or Existing CallerInfo, so we'll have to make do with
- // querying a new CallerInfo using the connection's phone number.
- String number = c.getAddress();
-
- if (info != null && info != CallGatewayManager.EMPTY_INFO) {
- // Gateway number, the connection number is actually the gateway number.
- // need to lookup via dialed number.
- number = info.trueNumber;
- }
-
- if (DBG) {
- log("PhoneUtils.startGetCallerInfo: new query for phone number...");
- log("- number (address): " + toLogSafePhoneNumber(number));
- log("- c: " + c);
- log("- phone: " + c.getCall().getPhone());
- int phoneType = c.getCall().getPhone().getPhoneType();
- log("- phoneType: " + phoneType);
- switch (phoneType) {
- case PhoneConstants.PHONE_TYPE_NONE: log(" ==> PHONE_TYPE_NONE"); break;
- case PhoneConstants.PHONE_TYPE_GSM: log(" ==> PHONE_TYPE_GSM"); break;
- case PhoneConstants.PHONE_TYPE_IMS: log(" ==> PHONE_TYPE_IMS"); break;
- case PhoneConstants.PHONE_TYPE_CDMA: log(" ==> PHONE_TYPE_CDMA"); break;
- case PhoneConstants.PHONE_TYPE_SIP: log(" ==> PHONE_TYPE_SIP"); break;
- case PhoneConstants.PHONE_TYPE_THIRD_PARTY:
- log(" ==> PHONE_TYPE_THIRD_PARTY");
- break;
- default: log(" ==> Unknown phone type"); break;
- }
- }
-
- cit = new CallerInfoToken();
- cit.currentInfo = new CallerInfo();
-
- // Store CNAP information retrieved from the Connection (we want to do this
- // here regardless of whether the number is empty or not).
- cit.currentInfo.cnapName = c.getCnapName();
- cit.currentInfo.setName(cit.currentInfo.cnapName); // This can still get overwritten
- // by ContactInfo later
- cit.currentInfo.numberPresentation = c.getNumberPresentation();
- cit.currentInfo.namePresentation = c.getCnapNamePresentation();
-
- if (VDBG) {
- log("startGetCallerInfo: number = " + number);
- log("startGetCallerInfo: CNAP Info from FW(1): name="
- + cit.currentInfo.cnapName
- + ", Name/Number Pres=" + cit.currentInfo.numberPresentation);
- }
-
- // handling case where number is null (caller id hidden) as well.
- if (!TextUtils.isEmpty(number)) {
- // Check for special CNAP cases and modify the CallerInfo accordingly
- // to be sure we keep the right information to display/log later
- number = modifyForSpecialCnapCases(context, cit.currentInfo, number,
- cit.currentInfo.numberPresentation);
-
- cit.currentInfo.setPhoneNumber(number);
- // For scenarios where we may receive a valid number from the network but a
- // restricted/unavailable presentation, we do not want to perform a contact query
- // (see note on isFinal above). So we set isFinal to true here as well.
- if (cit.currentInfo.numberPresentation != PhoneConstants.PRESENTATION_ALLOWED) {
- cit.isFinal = true;
- } else {
- if (DBG) log("==> Actually starting CallerInfoAsyncQuery.startQuery()...");
- cit.asyncQuery = CallerInfoAsyncQuery.startQuery(QUERY_TOKEN, context,
- number, sCallerInfoQueryListener, c);
- cit.asyncQuery.addQueryListener(QUERY_TOKEN, listener, cookie);
- cit.isFinal = false;
- }
- } else {
- // This is the case where we are querying on a number that
- // is null or empty, like a caller whose caller id is
- // blocked or empty (CLIR). The previous behaviour was to
- // throw a null CallerInfo object back to the user, but
- // this departure is somewhat cleaner.
- if (DBG) log("startGetCallerInfo: No query to start, send trivial reply.");
- cit.isFinal = true; // please see note on isFinal, above.
- }
-
- c.setUserData(cit);
-
- if (DBG) {
- log("startGetCallerInfo: query based on number: " + toLogSafePhoneNumber(number));
- }
-
- } else if (userDataObject instanceof CallerInfoToken) {
- // State (2): query is executing, but has not completed.
-
- // just tack on this listener to the queue.
- cit = (CallerInfoToken) userDataObject;
-
- // handling case where number is null (caller id hidden) as well.
- if (cit.asyncQuery != null) {
- cit.asyncQuery.addQueryListener(QUERY_TOKEN, listener, cookie);
-
- if (DBG) log("startGetCallerInfo: query already running, adding listener: " +
- listener.getClass().toString());
- } else {
- // handling case where number/name gets updated later on by the network
- String updatedNumber = c.getAddress();
-
- if (info != null) {
- // Gateway number, the connection number is actually the gateway number.
- // need to lookup via dialed number.
- updatedNumber = info.trueNumber;
- }
-
- if (DBG) {
- log("startGetCallerInfo: updatedNumber initially = "
- + toLogSafePhoneNumber(updatedNumber));
- }
- if (!TextUtils.isEmpty(updatedNumber)) {
- // Store CNAP information retrieved from the Connection
- cit.currentInfo.cnapName = c.getCnapName();
- // This can still get overwritten by ContactInfo
- cit.currentInfo.setName(cit.currentInfo.cnapName);
- cit.currentInfo.numberPresentation = c.getNumberPresentation();
- cit.currentInfo.namePresentation = c.getCnapNamePresentation();
-
- updatedNumber = modifyForSpecialCnapCases(context, cit.currentInfo,
- updatedNumber, cit.currentInfo.numberPresentation);
-
- cit.currentInfo.setPhoneNumber(updatedNumber);
- if (DBG) {
- log("startGetCallerInfo: updatedNumber="
- + toLogSafePhoneNumber(updatedNumber));
- }
- if (VDBG) {
- log("startGetCallerInfo: CNAP Info from FW(2): name="
- + cit.currentInfo.cnapName
- + ", Name/Number Pres=" + cit.currentInfo.numberPresentation);
- } else if (DBG) {
- log("startGetCallerInfo: CNAP Info from FW(2)");
- }
- // For scenarios where we may receive a valid number from the network but a
- // restricted/unavailable presentation, we do not want to perform a contact query
- // (see note on isFinal above). So we set isFinal to true here as well.
- if (cit.currentInfo.numberPresentation != PhoneConstants.PRESENTATION_ALLOWED) {
- cit.isFinal = true;
- } else {
- cit.asyncQuery = CallerInfoAsyncQuery.startQuery(QUERY_TOKEN, context,
- updatedNumber, sCallerInfoQueryListener, c);
- cit.asyncQuery.addQueryListener(QUERY_TOKEN, listener, cookie);
- cit.isFinal = false;
- }
- } else {
- if (DBG) log("startGetCallerInfo: No query to attach to, send trivial reply.");
- if (cit.currentInfo == null) {
- cit.currentInfo = new CallerInfo();
- }
- // Store CNAP information retrieved from the Connection
- cit.currentInfo.cnapName = c.getCnapName(); // This can still get
- // overwritten by ContactInfo
- cit.currentInfo.setName(cit.currentInfo.cnapName);
- cit.currentInfo.numberPresentation = c.getNumberPresentation();
- cit.currentInfo.namePresentation = c.getCnapNamePresentation();
-
- if (VDBG) {
- log("startGetCallerInfo: CNAP Info from FW(3): name="
- + cit.currentInfo.cnapName
- + ", Name/Number Pres=" + cit.currentInfo.numberPresentation);
- } else if (DBG) {
- log("startGetCallerInfo: CNAP Info from FW(3)");
- }
- cit.isFinal = true; // please see note on isFinal, above.
- }
- }
- } else {
- // State (3): query is complete.
-
- // The connection's userDataObject is a full-fledged
- // CallerInfo instance. Wrap it in a CallerInfoToken and
- // return it to the user.
-
- cit = new CallerInfoToken();
- cit.currentInfo = (CallerInfo) userDataObject;
- cit.asyncQuery = null;
- cit.isFinal = true;
- // since the query is already done, call the listener.
- if (DBG) log("startGetCallerInfo: query already done, returning CallerInfo");
- if (DBG) log("==> cit.currentInfo = " + cit.currentInfo);
- }
- return cit;
- }
-
- /**
- * Static CallerInfoAsyncQuery.OnQueryCompleteListener instance that
- * we use with all our CallerInfoAsyncQuery.startQuery() requests.
- */
- private static final int QUERY_TOKEN = -1;
- static CallerInfoAsyncQuery.OnQueryCompleteListener sCallerInfoQueryListener =
- new CallerInfoAsyncQuery.OnQueryCompleteListener () {
- /**
- * When the query completes, we stash the resulting CallerInfo
- * object away in the Connection's "userData" (where it will
- * later be retrieved by the in-call UI.)
- */
- public void onQueryComplete(int token, Object cookie, CallerInfo ci) {
- if (DBG) log("query complete, updating connection.userdata");
- Connection conn = (Connection) cookie;
-
- // Added a check if CallerInfo is coming from ContactInfo or from Connection.
- // If no ContactInfo, then we want to use CNAP information coming from network
- if (DBG) log("- onQueryComplete: CallerInfo:" + ci);
- if (ci.contactExists || ci.isEmergencyNumber() || ci.isVoiceMailNumber()) {
- // If the number presentation has not been set by
- // the ContactInfo, use the one from the
- // connection.
-
- // TODO: Need a new util method to merge the info
- // from the Connection in a CallerInfo object.
- // Here 'ci' is a new CallerInfo instance read
- // from the DB. It has lost all the connection
- // info preset before the query (see PhoneUtils
- // line 1334). We should have a method to merge
- // back into this new instance the info from the
- // connection object not set by the DB. If the
- // Connection already has a CallerInfo instance in
- // userData, then we could use this instance to
- // fill 'ci' in. The same routine could be used in
- // PhoneUtils.
- if (0 == ci.numberPresentation) {
- ci.numberPresentation = conn.getNumberPresentation();
- }
- } else {
- // No matching contact was found for this number.
- // Return a new CallerInfo based solely on the CNAP
- // information from the network.
-
- CallerInfo newCi = getCallerInfo(null, conn);
-
- // ...but copy over the (few) things we care about
- // from the original CallerInfo object:
- if (newCi != null) {
- newCi.setPhoneNumber(ci.getPhoneNumber()); // To get formatted phone number
- newCi.geoDescription = ci.geoDescription; // To get geo description string
- ci = newCi;
- }
- }
-
- if (DBG) log("==> Stashing CallerInfo " + ci + " into the connection...");
- conn.setUserData(ci);
- }
- };
-
-
- /**
- * Returns a single "name" for the specified given a CallerInfo object.
- * If the name is null, return defaultString as the default value, usually
- * context.getString(R.string.unknown).
- */
- static String getCompactNameFromCallerInfo(CallerInfo ci, Context context) {
- if (DBG) log("getCompactNameFromCallerInfo: info = " + ci);
-
- String compactName = null;
- if (ci != null) {
- if (TextUtils.isEmpty(ci.getName())) {
- // Perform any modifications for special CNAP cases to
- // the phone number being displayed, if applicable.
- compactName = modifyForSpecialCnapCases(context, ci, ci.getPhoneNumber(),
- ci.numberPresentation);
- } else {
- // Don't call modifyForSpecialCnapCases on regular name. See b/2160795.
- compactName = ci.getName();
- }
- }
-
- if ((compactName == null) || (TextUtils.isEmpty(compactName))) {
- // If we're still null/empty here, then check if we have a presentation
- // string that takes precedence that we could return, otherwise display
- // "unknown" string.
- if (ci != null && ci.numberPresentation == PhoneConstants.PRESENTATION_RESTRICTED) {
- compactName = context.getString(R.string.private_num);
- } else if (ci != null && ci.numberPresentation == PhoneConstants.PRESENTATION_PAYPHONE) {
- compactName = context.getString(R.string.payphone);
- } else {
- compactName = context.getString(R.string.unknown);
- }
- }
- if (VDBG) log("getCompactNameFromCallerInfo: compactName=" + compactName);
- return compactName;
- }
-
- static boolean isInEmergencyCall(CallManager cm) {
- Call fgCall = cm.getActiveFgCall();
- // isIdle includes checks for the DISCONNECTING/DISCONNECTED state.
- if(!fgCall.isIdle()) {
- for (Connection cn : fgCall.getConnections()) {
- if (PhoneNumberUtils.isLocalEmergencyNumber(PhoneGlobals.getInstance(),
- cn.getAddress())) {
- return true;
- }
- }
- }
- return false;
- }
//
// Misc UI policy helper functions
//
/**
- * Based on the input CNAP number string,
- * @return _RESTRICTED or _UNKNOWN for all the special CNAP strings.
- * Otherwise, return CNAP_SPECIAL_CASE_NO.
- */
- private static int checkCnapSpecialCases(String n) {
- if (n.equals("PRIVATE") ||
- n.equals("P") ||
- n.equals("RES")) {
- if (DBG) log("checkCnapSpecialCases, PRIVATE string: " + n);
- return PhoneConstants.PRESENTATION_RESTRICTED;
- } else if (n.equals("UNAVAILABLE") ||
- n.equals("UNKNOWN") ||
- n.equals("UNA") ||
- n.equals("U")) {
- if (DBG) log("checkCnapSpecialCases, UNKNOWN string: " + n);
- return PhoneConstants.PRESENTATION_UNKNOWN;
- } else {
- if (DBG) log("checkCnapSpecialCases, normal str. number: " + n);
- return CNAP_SPECIAL_CASE_NO;
- }
- }
-
- /**
- * Handles certain "corner cases" for CNAP. When we receive weird phone numbers
- * from the network to indicate different number presentations, convert them to
- * expected number and presentation values within the CallerInfo object.
- * @param number number we use to verify if we are in a corner case
- * @param presentation presentation value used to verify if we are in a corner case
- * @return the new String that should be used for the phone number
- */
- /* package */ static String modifyForSpecialCnapCases(Context context, CallerInfo ci,
- String number, int presentation) {
- // Obviously we return number if ci == null, but still return number if
- // number == null, because in these cases the correct string will still be
- // displayed/logged after this function returns based on the presentation value.
- if (ci == null || number == null) return number;
-
- if (DBG) {
- log("modifyForSpecialCnapCases: initially, number="
- + toLogSafePhoneNumber(number)
- + ", presentation=" + presentation + " ci " + ci);
- }
-
- // "ABSENT NUMBER" is a possible value we could get from the network as the
- // phone number, so if this happens, change it to "Unknown" in the CallerInfo
- // and fix the presentation to be the same.
- final String[] absentNumberValues =
- context.getResources().getStringArray(R.array.absent_num);
- if (Arrays.asList(absentNumberValues).contains(number)
- && presentation == PhoneConstants.PRESENTATION_ALLOWED) {
- number = context.getString(R.string.unknown);
- ci.numberPresentation = PhoneConstants.PRESENTATION_UNKNOWN;
- }
-
- // Check for other special "corner cases" for CNAP and fix them similarly. Corner
- // cases only apply if we received an allowed presentation from the network, so check
- // if we think we have an allowed presentation, or if the CallerInfo presentation doesn't
- // match the presentation passed in for verification (meaning we changed it previously
- // because it's a corner case and we're being called from a different entry point).
- if (ci.numberPresentation == PhoneConstants.PRESENTATION_ALLOWED
- || (ci.numberPresentation != presentation
- && presentation == PhoneConstants.PRESENTATION_ALLOWED)) {
- int cnapSpecialCase = checkCnapSpecialCases(number);
- if (cnapSpecialCase != CNAP_SPECIAL_CASE_NO) {
- // For all special strings, change number & numberPresentation.
- if (cnapSpecialCase == PhoneConstants.PRESENTATION_RESTRICTED) {
- number = context.getString(R.string.private_num);
- } else if (cnapSpecialCase == PhoneConstants.PRESENTATION_UNKNOWN) {
- number = context.getString(R.string.unknown);
- }
- if (DBG) {
- log("SpecialCnap: number=" + toLogSafePhoneNumber(number)
- + "; presentation now=" + cnapSpecialCase);
- }
- ci.numberPresentation = cnapSpecialCase;
- }
- }
- if (DBG) {
- log("modifyForSpecialCnapCases: returning number string="
- + toLogSafePhoneNumber(number));
- }
- return number;
- }
-
- //
- // Support for 3rd party phone service providers.
- //
-
- /**
* Check if a phone number can be route through a 3rd party
* gateway. The number must be a global phone number in numerical
* form (1-800-666-SEXY won't work).
diff --git a/src/com/android/phone/otasp/OtaspActivationService.java b/src/com/android/phone/otasp/OtaspActivationService.java
index 7490880..6ed2ea8 100644
--- a/src/com/android/phone/otasp/OtaspActivationService.java
+++ b/src/com/android/phone/otasp/OtaspActivationService.java
@@ -150,11 +150,9 @@
mPhone.registerForCdmaOtaStatusChange(mHandler, EVENT_CDMA_PROVISION_STATUS_UPDATE, null);
mPhone.registerForPreciseCallStateChanged(mHandler, EVENT_CALL_STATE_CHANGED, null);
logd("startNonInteractiveOtasp: placing call to '" + OTASP_NUMBER + "'...");
- int callStatus = PhoneUtils.placeCall(this,
+ int callStatus = PhoneUtils.placeOtaspCall(this,
getPhone(),
- OTASP_NUMBER,
- null, // contactRef
- false); // isEmergencyCall
+ OTASP_NUMBER);
if (callStatus == PhoneUtils.CALL_STATUS_DIALED) {
if (DBG) logd(" ==> success return from placeCall(): callStatus = " + callStatus);
} else {
diff --git a/src/com/android/phone/settings/PhoneAccountSettingsFragment.java b/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
index aa6b155..3811a77 100644
--- a/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
+++ b/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
@@ -101,7 +101,7 @@
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
- mTelecomManager = TelecomManager.from(getActivity());
+ mTelecomManager = getActivity().getSystemService(TelecomManager.class);
mTelephonyManager = TelephonyManager.from(getActivity());
mSubscriptionManager = SubscriptionManager.from(getActivity());
}
diff --git a/src/com/android/phone/vvm/VvmDumpHandler.java b/src/com/android/phone/vvm/VvmDumpHandler.java
index 866927e..82c5bb5 100644
--- a/src/com/android/phone/vvm/VvmDumpHandler.java
+++ b/src/com/android/phone/vvm/VvmDumpHandler.java
@@ -19,7 +19,7 @@
indentedWriter.println("******* OmtpVvm *******");
indentedWriter.println("======= Configs =======");
indentedWriter.increaseIndent();
- for (PhoneAccountHandle handle : TelecomManager.from(context)
+ for (PhoneAccountHandle handle : context.getSystemService(TelecomManager.class)
.getCallCapablePhoneAccounts()) {
int subId = PhoneAccountHandleConverter.toSubId(handle);
indentedWriter.println(
diff --git a/src/com/android/services/telephony/ConferenceParticipantConnection.java b/src/com/android/services/telephony/ConferenceParticipantConnection.java
index b1f1b23..ed92e7f 100644
--- a/src/com/android/services/telephony/ConferenceParticipantConnection.java
+++ b/src/com/android/services/telephony/ConferenceParticipantConnection.java
@@ -17,15 +17,13 @@
package com.android.services.telephony;
import android.net.Uri;
-import android.telecom.ConferenceParticipant;
import android.telecom.Connection;
import android.telecom.DisconnectCause;
-import android.telecom.PhoneAccount;
-import android.telephony.PhoneNumberUtils;
+import android.telephony.Rlog;
import android.telephony.SubscriptionInfo;
import android.text.TextUtils;
-import com.android.internal.annotations.VisibleForTesting;
+import com.android.ims.internal.ConferenceParticipant;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
@@ -34,6 +32,8 @@
*/
public class ConferenceParticipantConnection extends Connection {
+ private static final String LOG_TAG = "ConferenceParticipantConnection";
+
/**
* The user entity URI For the conference participant.
*/
@@ -88,7 +88,7 @@
* @param newState The new state.
*/
public void updateState(int newState) {
- Log.v(this, "updateState endPoint: %s state: %s", Log.pii(mEndpoint),
+ Log.v(this, "updateState endPoint: %s state: %s", Rlog.pii(LOG_TAG, mEndpoint),
Connection.stateToString(newState));
if (newState == getState()) {
return;
@@ -203,13 +203,13 @@
sb.append("[ConferenceParticipantConnection objId:");
sb.append(System.identityHashCode(this));
sb.append(" endPoint:");
- sb.append(Log.pii(mEndpoint));
+ sb.append(Rlog.pii(LOG_TAG, mEndpoint));
sb.append(" address:");
- sb.append(Log.pii(getAddress()));
+ sb.append(Rlog.pii(LOG_TAG, getAddress()));
sb.append(" addressPresentation:");
sb.append(getAddressPresentation());
sb.append(" parentConnection:");
- sb.append(Log.pii(mParentConnection.getAddress()));
+ sb.append(Rlog.pii(LOG_TAG, mParentConnection.getAddress()));
sb.append(" state:");
sb.append(Connection.stateToString(getState()));
sb.append(" connectTime:");
diff --git a/src/com/android/services/telephony/HoldTracker.java b/src/com/android/services/telephony/HoldTracker.java
index 805802f..5032b41 100644
--- a/src/com/android/services/telephony/HoldTracker.java
+++ b/src/com/android/services/telephony/HoldTracker.java
@@ -16,7 +16,6 @@
package com.android.services.telephony;
-import android.telecom.Log;
import android.telecom.PhoneAccountHandle;
import java.util.ArrayList;
diff --git a/src/com/android/services/telephony/ImsConference.java b/src/com/android/services/telephony/ImsConference.java
index 17549cf..b47adb2 100644
--- a/src/com/android/services/telephony/ImsConference.java
+++ b/src/com/android/services/telephony/ImsConference.java
@@ -21,19 +21,19 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.PersistableBundle;
-import android.telecom.ConferenceParticipant;
import android.telecom.Connection;
import android.telecom.Connection.VideoProvider;
import android.telecom.DisconnectCause;
-import android.telecom.Log;
import android.telecom.PhoneAccountHandle;
import android.telecom.StatusHints;
import android.telecom.TelecomManager;
import android.telecom.VideoProfile;
import android.telephony.CarrierConfigManager;
import android.telephony.PhoneNumberUtils;
+import android.telephony.Rlog;
import android.util.Pair;
+import com.android.ims.internal.ConferenceParticipant;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.CallStateException;
@@ -69,6 +69,8 @@
*/
public class ImsConference extends TelephonyConferenceBase implements Holdable {
+ private static final String LOG_TAG = "ImsConference";
+
/**
* Abstracts out fetching a feature flag. Makes testing easier.
*/
@@ -168,7 +170,7 @@
return;
}
- sendConnectionEvent(event, extras);
+ sendConferenceEvent(event, extras);
}
@Override
@@ -328,15 +330,15 @@
conferenceCapabilities = changeBitmask(conferenceCapabilities,
Connection.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL,
- can(capabilities, Connection.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL));
+ (capabilities & Connection.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL) != 0);
if (isVideoConferencingSupported) {
conferenceCapabilities = changeBitmask(conferenceCapabilities,
Connection.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL,
- can(capabilities, Connection.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL));
+ (capabilities & Connection.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL) != 0);
conferenceCapabilities = changeBitmask(conferenceCapabilities,
Connection.CAPABILITY_CAN_UPGRADE_TO_VIDEO,
- can(capabilities, Connection.CAPABILITY_CAN_UPGRADE_TO_VIDEO));
+ (capabilities & Connection.CAPABILITY_CAN_UPGRADE_TO_VIDEO) != 0);
} else {
// If video conferencing is not supported, explicitly turn off the remote video
// capability and the ability to upgrade to video.
@@ -349,7 +351,7 @@
conferenceCapabilities = changeBitmask(conferenceCapabilities,
Connection.CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO,
- can(capabilities, Connection.CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO));
+ (capabilities & Connection.CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO) != 0);
conferenceCapabilities = changeBitmask(conferenceCapabilities,
Connection.CAPABILITY_CAN_PAUSE_VIDEO,
@@ -368,15 +370,15 @@
private int applyHostProperties(int conferenceProperties, int properties) {
conferenceProperties = changeBitmask(conferenceProperties,
Connection.PROPERTY_HIGH_DEF_AUDIO,
- can(properties, Connection.PROPERTY_HIGH_DEF_AUDIO));
+ (properties & Connection.PROPERTY_HIGH_DEF_AUDIO) != 0);
conferenceProperties = changeBitmask(conferenceProperties,
Connection.PROPERTY_WIFI,
- can(properties, Connection.PROPERTY_WIFI));
+ (properties & Connection.PROPERTY_WIFI) != 0);
conferenceProperties = changeBitmask(conferenceProperties,
Connection.PROPERTY_IS_EXTERNAL_CALL,
- can(properties, Connection.PROPERTY_IS_EXTERNAL_CALL));
+ (properties & Connection.PROPERTY_IS_EXTERNAL_CALL) != 0);
conferenceProperties = changeBitmask(conferenceProperties,
Connection.PROPERTY_REMOTELY_HOSTED, !isConferenceHost());
@@ -602,7 +604,8 @@
* that the conference is represented appropriately on Bluetooth devices.
*/
private void updateManageConference() {
- boolean couldManageConference = can(Connection.CAPABILITY_MANAGE_CONFERENCE);
+ boolean couldManageConference =
+ (getConnectionCapabilities() & Connection.CAPABILITY_MANAGE_CONFERENCE) != 0;
boolean canManageConference = mFeatureFlagProxy.isUsingSinglePartyCallEmulation()
&& mIsEmulatingSinglePartyCall
? mConferenceParticipantConnections.size() > 1
@@ -822,8 +825,8 @@
if (!participantUserEntities.contains(entry.getKey())) {
ConferenceParticipantConnection participant = entry.getValue();
participant.setDisconnected(new DisconnectCause(DisconnectCause.CANCELED));
- mTelephonyConnectionService.removeConnection(participant);
removeTelephonyConnection(participant);
+ participant.destroy();
entryIterator.remove();
oldParticipantsRemoved = true;
}
@@ -940,8 +943,8 @@
// again anyways.
entry.setDisconnected(new DisconnectCause(DisconnectCause.CANCELED,
DisconnectCause.REASON_EMULATING_SINGLE_CALL));
- mTelephonyConnectionService.removeConnection(entry);
removeTelephonyConnection(entry);
+ entry.destroy();
valueIterator.remove();
}
@@ -949,7 +952,8 @@
setConferenceState(false);
// Remove manage conference capability.
- mCouldManageConference = can(Connection.CAPABILITY_MANAGE_CONFERENCE);
+ mCouldManageConference =
+ (getConnectionCapabilities() & Connection.CAPABILITY_MANAGE_CONFERENCE) != 0;
int currentCapabilities = getConnectionCapabilities();
currentCapabilities &= ~Connection.CAPABILITY_MANAGE_CONFERENCE;
setConnectionCapabilities(currentCapabilities);
@@ -1009,7 +1013,7 @@
mConferenceParticipantConnections.remove(new Pair<>(participant.getUserEntity(),
participant.getEndpoint()));
}
- mTelephonyConnectionService.removeConnection(participant);
+ participant.destroy();
}
/**
@@ -1025,7 +1029,6 @@
// Mark disconnect cause as cancelled to ensure that the call is not logged in the
// call log.
connection.setDisconnected(new DisconnectCause(DisconnectCause.CANCELED));
- mTelephonyConnectionService.removeConnection(connection);
connection.destroy();
handleConnectionDestruction(connection);
}
@@ -1086,7 +1089,7 @@
boolean isHost = PhoneNumberUtils.compare(hostNumber, number);
Log.v(this, "isParticipantHost(%s) : host: %s, participant %s", (isHost ? "Y" : "N"),
- Log.pii(hostNumber), Log.pii(number));
+ Rlog.pii(LOG_TAG, hostNumber), Rlog.pii(LOG_TAG, number));
if (isHost) {
return true;
@@ -1209,8 +1212,8 @@
*/
private boolean isVideoCapable() {
int capabilities = mConferenceHost.getConnectionCapabilities();
- return can(capabilities, Connection.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL)
- && can(capabilities, Connection.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL);
+ return (capabilities & Connection.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL) != 0
+ && (capabilities & Connection.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL) != 0;
}
private void updateStatusHints() {
diff --git a/src/com/android/services/telephony/ImsConferenceController.java b/src/com/android/services/telephony/ImsConferenceController.java
index 315aaad..1e10055 100644
--- a/src/com/android/services/telephony/ImsConferenceController.java
+++ b/src/com/android/services/telephony/ImsConferenceController.java
@@ -22,6 +22,7 @@
import android.telecom.ConnectionService;
import android.telecom.DisconnectCause;
import android.telecom.PhoneAccountHandle;
+import android.telephony.Rlog;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
@@ -38,11 +39,13 @@
* Manages conferences for IMS connections.
*/
public class ImsConferenceController {
+ private static final String LOG_TAG = "ImsConferenceController";
/**
* Conference listener; used to receive notification when a conference has been disconnected.
*/
- private final Conference.Listener mConferenceListener = new Conference.Listener() {
+ private final TelephonyConferenceBase.TelephonyConferenceListener mConferenceListener =
+ new TelephonyConferenceBase.TelephonyConferenceListener() {
@Override
public void onDestroyed(Conference conference) {
if (Log.VERBOSE) {
@@ -69,13 +72,13 @@
@Override
public void onStateChanged(Connection c, int state) {
- Log.v(this, "onStateChanged: %s", Log.pii(c.getAddress()));
+ Log.v(this, "onStateChanged: %s", Rlog.pii(LOG_TAG, c.getAddress()));
recalculate();
}
@Override
public void onDisconnected(Connection c, DisconnectCause disconnectCause) {
- Log.v(this, "onDisconnected: %s", Log.pii(c.getAddress()));
+ Log.v(this, "onDisconnected: %s", Rlog.pii(LOG_TAG, c.getAddress()));
recalculate();
}
@@ -147,6 +150,7 @@
mTelephonyConnections.add(connection);
connection.addTelephonyConnectionListener(mTelephonyConnectionListener);
recalculateConference();
+ recalculateConferenceable();
}
/**
@@ -379,7 +383,7 @@
ImsConference conference = new ImsConference(mTelecomAccountRegistry, mConnectionService,
conferenceHostConnection, phoneAccountHandle, mFeatureFlagProxy);
conference.setState(conferenceHostConnection.getState());
- conference.addListener(mConferenceListener);
+ conference.addTelephonyConferenceListener(mConferenceListener);
conference.updateConferenceParticipantsAfterCreation();
mConnectionService.addConference(conference);
conferenceHostConnection.setTelecomCallId(conference.getTelecomCallId());
diff --git a/src/com/android/services/telephony/Log.java b/src/com/android/services/telephony/Log.java
index 9941a59..57bf849 100644
--- a/src/com/android/services/telephony/Log.java
+++ b/src/com/android/services/telephony/Log.java
@@ -16,8 +16,6 @@
package com.android.services.telephony;
-import android.content.Context;
-
/**
* Manages logging for the entire module.
*/
@@ -39,72 +37,80 @@
return FORCE_LOGGING || android.util.Log.isLoggable(TAG, level);
}
- public static void initLogging(Context context) {
- // Register Telephony with the Telecom Logger.
- android.telecom.Log.setTag(TAG);
- android.telecom.Log.setSessionContext(context);
- }
-
// Relay log messages to Telecom
// TODO: Redo namespace of Telephony to use these methods directly.
public static void d(String prefix, String format, Object... args) {
- android.telecom.Log.d(prefix, format, args);
+ android.util.Log.d(TAG, (args == null || args.length == 0) ? format :
+ String.format(prefix + ": " + format, args));
}
public static void d(Object objectPrefix, String format, Object... args) {
- android.telecom.Log.d(objectPrefix, format, args);
+ android.util.Log.d(TAG, (args == null || args.length == 0) ? format :
+ String.format(getPrefixFromObject(objectPrefix) + ": " + format, args));
}
public static void i(String prefix, String format, Object... args) {
- android.telecom.Log.i(prefix, format, args);
+ android.util.Log.i(TAG, (args == null || args.length == 0) ? format :
+ String.format(prefix + ": " + format, args));
}
public static void i(Object objectPrefix, String format, Object... args) {
- android.telecom.Log.i(objectPrefix, format, args);
+ android.util.Log.i(TAG, (args == null || args.length == 0) ? format :
+ String.format(getPrefixFromObject(objectPrefix) + ": " + format, args));
}
public static void v(String prefix, String format, Object... args) {
- android.telecom.Log.v(prefix, format, args);
+ android.util.Log.v(TAG, (args == null || args.length == 0) ? format :
+ String.format(prefix + ": " + format, args));
}
public static void v(Object objectPrefix, String format, Object... args) {
- android.telecom.Log.v(objectPrefix, format, args);
+ android.util.Log.v(TAG, (args == null || args.length == 0) ? format :
+ String.format(getPrefixFromObject(objectPrefix) + ": " + format, args));
}
public static void w(String prefix, String format, Object... args) {
- android.telecom.Log.w(prefix, format, args);
+ android.util.Log.w(TAG, (args == null || args.length == 0) ? format :
+ String.format(prefix + ": " + format, args));
}
public static void w(Object objectPrefix, String format, Object... args) {
- android.telecom.Log.w(objectPrefix, format, args);
+ android.util.Log.w(TAG, (args == null || args.length == 0) ? format :
+ String.format(getPrefixFromObject(objectPrefix) + ": " + format, args));
}
public static void e(String prefix, Throwable tr, String format, Object... args) {
- android.telecom.Log.e(prefix, tr, format, args);
+ android.util.Log.e(TAG, (args == null || args.length == 0) ? format :
+ String.format(prefix + ": " + format, args), tr);
}
public static void e(Object objectPrefix, Throwable tr, String format, Object... args) {
- android.telecom.Log.e(objectPrefix, tr, format, args);
+ android.util.Log.e(TAG, (args == null || args.length == 0) ? format :
+ String.format(getPrefixFromObject(objectPrefix) + ": " + format, args), tr);
}
public static void wtf(String prefix, Throwable tr, String format, Object... args) {
- android.telecom.Log.wtf(prefix, tr, format, args);
+ android.util.Log.wtf(TAG, (args == null || args.length == 0) ? format :
+ String.format(prefix + ": " + format, args), tr);
}
public static void wtf(Object objectPrefix, Throwable tr, String format, Object... args) {
- android.telecom.Log.wtf(objectPrefix, tr, format, args);
+ android.util.Log.wtf(TAG, (args == null || args.length == 0) ? format :
+ String.format(getPrefixFromObject(objectPrefix) + ": " + format, args), tr);
}
public static void wtf(String prefix, String format, Object... args) {
- android.telecom.Log.wtf(prefix, format, args);
+ android.util.Log.wtf(TAG, (args == null || args.length == 0) ? format :
+ String.format(prefix + ": " + format, args));
}
public static void wtf(Object objectPrefix, String format, Object... args) {
- android.telecom.Log.wtf(objectPrefix, format, args);
+ android.util.Log.wtf(TAG, (args == null || args.length == 0) ? format :
+ String.format(getPrefixFromObject(objectPrefix) + ": " + format, args));
}
- public static String pii(Object pii) {
- return android.telecom.Log.pii(pii);
+ private static String getPrefixFromObject(Object obj) {
+ return obj == null ? "<null>" : obj.getClass().getSimpleName();
}
}
diff --git a/src/com/android/services/telephony/PstnIncomingCallNotifier.java b/src/com/android/services/telephony/PstnIncomingCallNotifier.java
index a2ced9e..f397dce 100644
--- a/src/com/android/services/telephony/PstnIncomingCallNotifier.java
+++ b/src/com/android/services/telephony/PstnIncomingCallNotifier.java
@@ -25,6 +25,7 @@
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
+import android.telephony.Rlog;
import android.text.TextUtils;
import com.android.internal.telephony.Call;
@@ -49,6 +50,8 @@
* occurence. One instance of these exists for each of the telephony-based call services.
*/
final class PstnIncomingCallNotifier {
+ private static final String LOG_TAG = "PstnIncomingCallNotifier";
+
/** New ringing connection event code. */
private static final int EVENT_NEW_RINGING_CONNECTION = 100;
private static final int EVENT_CDMA_CALL_WAITING = 101;
@@ -181,7 +184,7 @@
// Presentation of the number is allowed, so we ensure the number matches the
// one in the call waiting information.
Log.i(this, "handleCdmaCallWaiting: inform telecom of waiting call; "
- + "number = %s", Log.pii(number));
+ + "number = %s", Rlog.pii(LOG_TAG, number));
sendIncomingCallIntent(connection);
} else {
Log.w(this, "handleCdmaCallWaiting: presentation or number do not match, not"
@@ -248,7 +251,8 @@
// connection already disconnected. Do nothing
}
} else {
- TelecomManager.from(mPhone.getContext()).addNewUnknownCall(handle, extras);
+ TelecomManager tm = mPhone.getContext().getSystemService(TelecomManager.class);
+ tm.addNewUnknownCall(handle, extras);
}
} else {
Log.i(this, "swapped an old connection, new one is: %s", connection);
@@ -283,7 +287,8 @@
// connection already disconnected. Do nothing
}
} else {
- TelecomManager.from(mPhone.getContext()).addNewIncomingCall(handle, extras);
+ TelecomManager tm = mPhone.getContext().getSystemService(TelecomManager.class);
+ tm.addNewIncomingCall(handle, extras);
}
}
diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java
index 2e923ec..8bf9d42 100644
--- a/src/com/android/services/telephony/TelecomAccountRegistry.java
+++ b/src/com/android/services/telephony/TelecomAccountRegistry.java
@@ -42,6 +42,7 @@
import android.telecom.TelecomManager;
import android.telephony.CarrierConfigManager;
import android.telephony.PhoneStateListener;
+import android.telephony.Rlog;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
@@ -72,6 +73,7 @@
*/
public class TelecomAccountRegistry {
private static final boolean DBG = false; /* STOP SHIP if true */
+ private static final String LOG_TAG = "TelecomAccountRegistry";
// This icon is the one that is used when the Slot ID that we have for a particular SIM
// is not supported, i.e. SubscriptionManager.INVALID_SLOT_ID or the 5th SIM in a phone.
@@ -390,7 +392,7 @@
}
if(isMergedSim) {
groupId = GROUP_PREFIX + line1Number;
- Log.i(this, "Adding Merged Account with group: " + Log.pii(groupId));
+ Log.i(this, "Adding Merged Account with group: " + Rlog.pii(LOG_TAG, groupId));
}
PhoneAccount account = PhoneAccount.builder(phoneAccountHandle, label)
@@ -876,7 +878,7 @@
TelecomAccountRegistry(Context context) {
mContext = context;
- mTelecomManager = TelecomManager.from(context);
+ mTelecomManager = context.getSystemService(TelecomManager.class);
mTelephonyManager = TelephonyManager.from(context);
mSubscriptionManager = SubscriptionManager.from(context);
}
@@ -1148,7 +1150,7 @@
R.bool.config_emergency_account_emergency_calls_only);
List<PhoneAccountHandle> accountHandles = emergencyCallsOnlyEmergencyAccount
? mTelecomManager.getAllPhoneAccountHandles()
- : mTelecomManager.getCallCapablePhoneAccounts(true /* includeDisabled */);
+ : mTelecomManager.getCallCapablePhoneAccounts();
for (PhoneAccountHandle handle : accountHandles) {
if (telephonyComponentName.equals(handle.getComponentName()) &&
diff --git a/src/com/android/services/telephony/TelephonyConferenceBase.java b/src/com/android/services/telephony/TelephonyConferenceBase.java
index 31d0f56..a8bbf64 100644
--- a/src/com/android/services/telephony/TelephonyConferenceBase.java
+++ b/src/com/android/services/telephony/TelephonyConferenceBase.java
@@ -20,6 +20,8 @@
import android.telecom.Conference;
import android.telecom.Connection;
import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import android.telephony.ServiceState;
import java.util.Collections;
import java.util.Iterator;
@@ -32,6 +34,8 @@
* all of these conferences use.
*/
public class TelephonyConferenceBase extends Conference {
+ private static final String TAG = "TelephonyConferenceBase";
+
/**
* Listener for conference events.
*/
@@ -40,7 +44,13 @@
* Listener called when a connection is added or removed from a conference.
* @param connection The connection.
*/
- public void onConferenceMembershipChanged(Connection connection) {};
+ public void onConferenceMembershipChanged(Connection connection) {}
+
+ /**
+ * Listener called when a conference is destroyed.
+ * @param conference The conference.
+ */
+ public void onDestroyed(Conference conference) {}
}
private final Set<TelephonyConferenceListener> mListeners = Collections.newSetFromMap(
@@ -50,7 +60,7 @@
* Adds a listener to this conference.
* @param listener The listener.
*/
- public void addListener(@NonNull TelephonyConferenceListener listener) {
+ public void addTelephonyConferenceListener(@NonNull TelephonyConferenceListener listener) {
mListeners.add(listener);
}
@@ -58,7 +68,7 @@
* Removes a listener from this conference.
* @param listener The listener.
*/
- public void removeListener(@NonNull TelephonyConferenceListener listener) {
+ public void removeTelephonyConferenceListener(@NonNull TelephonyConferenceListener listener) {
mListeners.remove(listener);
}
@@ -114,6 +124,46 @@
removeTelephonyConnection(connectionIterator.next());
}
destroy();
+ notifyDestroyed();
+ }
+
+ /**
+ * Updates RIL voice radio technology used for current conference after its creation.
+ */
+ public void updateCallRadioTechAfterCreation() {
+ final Connection primaryConnection = getPrimaryConnection();
+ if (primaryConnection != null && primaryConnection instanceof TelephonyConnection) {
+ TelephonyConnection telephonyConnection = (TelephonyConnection) primaryConnection;
+ putExtra(TelecomManager.EXTRA_CALL_NETWORK_TYPE,
+ ServiceState.rilRadioTechnologyToNetworkType(
+ telephonyConnection.getCallRadioTech()));
+ } else {
+ Log.w(TAG, "No primary connection found while updateCallRadioTechAfterCreation");
+ }
+ }
+
+ /**
+ * Removes the specified capability from the set of capabilities of this {@code Conference}.
+ *
+ * @param capability The capability to remove from the set.
+ */
+ public void removeCapability(int capability) {
+ int newCapabilities = getConnectionCapabilities();
+ newCapabilities &= ~capability;
+
+ setConnectionCapabilities(newCapabilities);
+ }
+
+ /**
+ * Adds the specified capability to the set of capabilities of this {@code Conference}.
+ *
+ * @param capability The capability to add to the set.
+ */
+ public void addCapability(int capability) {
+ int newCapabilities = getConnectionCapabilities();
+ newCapabilities |= capability;
+
+ setConnectionCapabilities(newCapabilities);
}
/**
@@ -126,4 +176,13 @@
listener.onConferenceMembershipChanged(connection);
}
}
+
+ /**
+ * Notifies {@link TelephonyConferenceListener}s of a conference being destroyed
+ */
+ private void notifyDestroyed() {
+ for (TelephonyConferenceListener listener : mListeners) {
+ listener.onDestroyed(this);
+ }
+ }
}
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index c1d2995..3282d06 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -29,7 +29,6 @@
import android.os.PersistableBundle;
import android.telecom.CallAudioState;
import android.telecom.Conference;
-import android.telecom.ConferenceParticipant;
import android.telecom.Connection;
import android.telecom.ConnectionService;
import android.telecom.PhoneAccount;
@@ -40,6 +39,7 @@
import android.telephony.CarrierConfigManager;
import android.telephony.DisconnectCause;
import android.telephony.PhoneNumberUtils;
+import android.telephony.Rlog;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.telephony.ims.ImsCallProfile;
@@ -47,6 +47,7 @@
import android.util.Pair;
import com.android.ims.ImsCall;
+import com.android.ims.internal.ConferenceParticipant;
import com.android.internal.os.SomeArgs;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.CallFailCause;
@@ -78,6 +79,8 @@
* Base class for CDMA and GSM connections.
*/
abstract class TelephonyConnection extends Connection implements Holdable {
+ private static final String LOG_TAG = "TelephonyConnection";
+
private static final int MSG_PRECISE_CALL_STATE_CHANGED = 1;
private static final int MSG_RINGBACK_TONE = 2;
private static final int MSG_HANDOVER_STATE_CHANGED = 3;
@@ -1608,8 +1611,8 @@
for (String key : extras.keySet()) {
Object value = extras.get(key);
if (value instanceof String) {
- Log.d(this, "updateExtras Key=" + Log.pii(key) +
- " value=" + Log.pii((String)value));
+ Log.d(this, "updateExtras Key=" + Rlog.pii(LOG_TAG, key)
+ + " value=" + Rlog.pii(LOG_TAG, value));
}
}
}
@@ -1632,7 +1635,7 @@
Log.d(this, "Extras update not required");
}
} else {
- Log.d(this, "updateExtras extras: " + Log.pii(extras));
+ Log.d(this, "updateExtras extras: " + Rlog.pii(LOG_TAG, extras));
}
}
}
@@ -2392,7 +2395,7 @@
sb.append(" properties:");
sb.append(propertiesToString(getConnectionProperties()));
sb.append(" address:");
- sb.append(Log.pii(getAddress()));
+ sb.append(Rlog.pii(LOG_TAG, getAddress()));
sb.append(" originalConnection:");
sb.append(mOriginalConnection);
sb.append(" partOfConf:");
@@ -2556,6 +2559,50 @@
}
/**
+ * Sets RIL voice radio technology used for current connection.
+ * <p>
+ * This property is set by the Telephony {@link ConnectionService}.
+ *
+ * @param vrat the RIL Voice Radio Technology used for current connection,
+ * see {@code RIL_RADIO_TECHNOLOGY_*} in {@link android.telephony.ServiceState}.
+ */
+ public final void setCallRadioTech(@ServiceState.RilRadioTechnology int vrat) {
+ Bundle extras = getExtras();
+ if (extras == null) {
+ extras = new Bundle();
+ }
+ extras.putInt(TelecomManager.EXTRA_CALL_NETWORK_TYPE,
+ ServiceState.rilRadioTechnologyToNetworkType(vrat));
+ putExtras(extras);
+ // Propagates the call radio technology to its parent {@link android.telecom.Conference}
+ // This action only covers non-IMS CS conference calls.
+ // For IMS PS call conference call, it can be updated via its host connection
+ // {@link #Listener.onExtrasChanged} event.
+ if (getConference() != null) {
+ getConference().putExtra(TelecomManager.EXTRA_CALL_NETWORK_TYPE,
+ ServiceState.rilRadioTechnologyToNetworkType(vrat));
+ }
+ }
+
+ /**
+ * Returns RIL voice radio technology used for current connection.
+ * <p>
+ * Used by the Telephony {@link ConnectionService}.
+ *
+ * @return the RIL voice radio technology used for current connection,
+ * see {@code RIL_RADIO_TECHNOLOGY_*} in {@link android.telephony.ServiceState}.
+ */
+ public final @ServiceState.RilRadioTechnology int getCallRadioTech() {
+ int voiceNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
+ Bundle extras = getExtras();
+ if (extras != null) {
+ voiceNetworkType = extras.getInt(TelecomManager.EXTRA_CALL_NETWORK_TYPE,
+ TelephonyManager.NETWORK_TYPE_UNKNOWN);
+ }
+ return ServiceState.networkTypeToRilRadioTechnology(voiceNetworkType);
+ }
+
+ /**
* Notifies {@link TelephonyConnectionListener}s of a change to conference participant data
* received via the {@link ImsConference} (i.e. conference event package).
*
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 1b60a5e..8de8c03 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -110,10 +110,6 @@
TelephonyConnectionService.this.addTelephonyConference(mImsConference);
}
@Override
- public void removeConnection(Connection connection) {
- TelephonyConnectionService.this.removeConnection(connection);
- }
- @Override
public void addExistingConnection(PhoneAccountHandle phoneAccountHandle,
Connection connection) {
TelephonyConnectionService.this
@@ -129,11 +125,6 @@
public void addConnectionToConferenceController(TelephonyConnection connection) {
TelephonyConnectionService.this.addConnectionToConferenceController(connection);
}
-
- @Override
- public void onConferenceMembershipChanged(Connection connection) {
- mHoldTracker.updateHoldCapability(connection.getPhoneAccountHandle());
- }
};
private final BroadcastReceiver mTtyBroadcastReceiver = new BroadcastReceiver() {
@@ -329,7 +320,6 @@
@Override
public void onCreate() {
super.onCreate();
- Log.initLogging(this);
setTelephonyManagerProxy(new TelephonyManagerProxyImpl(getApplicationContext()));
mExpectedComponentName = new ComponentName(this, this.getClass());
mEmergencyTonePlayer = new EmergencyTonePlayer(this);
@@ -1801,7 +1791,8 @@
// If the CDMA conference has not been merged, add-call will not work, so fail
// this request to add a call.
- if (cdmaConf.can(Connection.CAPABILITY_MERGE_CONFERENCE)) {
+ if ((cdmaConf.getConnectionCapabilities()
+ & Connection.CAPABILITY_MERGE_CONFERENCE) != 0) {
return Connection.createFailedConnection(new DisconnectCause(
DisconnectCause.RESTRICTED,
null,
@@ -1878,6 +1869,6 @@
*/
public void addTelephonyConference(@NonNull TelephonyConferenceBase conference) {
addConference(conference);
- conference.addListener(mTelephonyConferenceListener);
+ conference.addTelephonyConferenceListener(mTelephonyConferenceListener);
}
}
diff --git a/src/com/android/services/telephony/TelephonyConnectionServiceProxy.java b/src/com/android/services/telephony/TelephonyConnectionServiceProxy.java
index 604cf03..6c29bd2 100644
--- a/src/com/android/services/telephony/TelephonyConnectionServiceProxy.java
+++ b/src/com/android/services/telephony/TelephonyConnectionServiceProxy.java
@@ -30,16 +30,9 @@
Collection<Connection> getAllConnections();
void addConference(TelephonyConference mTelephonyConference);
void addConference(ImsConference mImsConference);
- void removeConnection(Connection connection);
void addExistingConnection(PhoneAccountHandle phoneAccountHandle,
Connection connection);
void addExistingConnection(PhoneAccountHandle phoneAccountHandle,
Connection connection, Conference conference);
void addConnectionToConferenceController(TelephonyConnection connection);
-
- /**
- * Called when a connection's conference membership changes.
- * @param connection The connection.
- */
- void onConferenceMembershipChanged(Connection connection);
}
diff --git a/tests/Android.mk b/tests/Android.mk
index 44bf176..a8bd204 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -26,7 +26,7 @@
LOCAL_MODULE_TAGS := tests
-LOCAL_JAVA_LIBRARIES := telephony-common android.test.base
+LOCAL_JAVA_LIBRARIES := telephony-common android.test.base ims-common
LOCAL_INSTRUMENTATION_FOR := TeleService
diff --git a/tests/src/com/android/phone/CnapTest.java b/tests/src/com/android/phone/CnapTest.java
deleted file mode 100644
index 534d02a..0000000
--- a/tests/src/com/android/phone/CnapTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// Need to be in this package to access package methods.
-package com.android.phone;
-import android.content.Context;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.telephony.CallerInfo;
-
-import static com.android.internal.telephony.PhoneConstants.PRESENTATION_ALLOWED;
-import static com.android.internal.telephony.PhoneConstants.PRESENTATION_UNKNOWN;
-
-// Test suite for the Caller Name Presentation (CNAP) handling.
-// See AndroidManifest.xml how to run these tests.
-public class CnapTest extends AndroidTestCase {
- private static final String TAG = "CnapTest";
- private Context mContext;
- private CallerInfo mCallerInfo;
- // TODO: This string should be loaded from the phone package and
- // not hardcoded.
- private String mUnknown = "Unknown";
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mContext = getContext();
- mCallerInfo = new CallerInfo();
- }
-
- // Checks the cnap 'ABSENT NUMBER' is mapped to the unknown presentation.
- @SmallTest
- public void testAbsentNumberIsMappedToUnknown() throws Exception {
- String num = modifyForSpecialCnapCases("ABSENT NUMBER", PRESENTATION_ALLOWED);
- assertIsUnknown(num);
- }
-
- // HELPERS
-
- /**
- * Checks the number and CallerInfo structure indicate the number
- * is unknown.
- */
- private void assertIsUnknown(String number) {
- assertEquals(mUnknown, number);
- assertEquals(PRESENTATION_UNKNOWN, mCallerInfo.numberPresentation);
- // TODO: cnapName and name presentation should be set to
- // unknown. At least I cannot see why it shouldn't be the case
- // assertEquals(mUnknown, mCallerInfo.cnapName);
- // assertEquals(PRESENTATION_UNKNOWN, mCallerInfo.namePresentation);
- }
-
- /**
- * Shorthand for PhoneUtils.modifyForSpecialCnapCases(mContext, mCallerInfo, ...)
- */
- private String modifyForSpecialCnapCases(String number, int presentation) {
- return PhoneUtils.modifyForSpecialCnapCases(
- mContext, mCallerInfo, number, presentation);
- }
-}
diff --git a/tests/src/com/android/services/telephony/ConferenceParticipantConnectionTest.java b/tests/src/com/android/services/telephony/ConferenceParticipantConnectionTest.java
index 4336a20..ede0965 100644
--- a/tests/src/com/android/services/telephony/ConferenceParticipantConnectionTest.java
+++ b/tests/src/com/android/services/telephony/ConferenceParticipantConnectionTest.java
@@ -16,7 +16,7 @@
package com.android.services.telephony;
-import static android.telecom.ConferenceParticipant.getParticipantAddress;
+import static com.android.ims.internal.ConferenceParticipant.getParticipantAddress;
import static org.junit.Assert.assertEquals;
diff --git a/tests/src/com/android/services/telephony/ImsConferenceTest.java b/tests/src/com/android/services/telephony/ImsConferenceTest.java
index 6f8b3e8..7251402 100644
--- a/tests/src/com/android/services/telephony/ImsConferenceTest.java
+++ b/tests/src/com/android/services/telephony/ImsConferenceTest.java
@@ -31,11 +31,12 @@
import android.os.Looper;
import android.telecom.Call;
import android.telecom.Conference;
-import android.telecom.ConferenceParticipant;
import android.telecom.Connection;
import android.telecom.PhoneAccountHandle;
import android.test.suitebuilder.annotation.SmallTest;
+import com.android.ims.internal.ConferenceParticipant;
+
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
@@ -97,8 +98,6 @@
imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
Arrays.asList(participant1));
assertEquals(0, imsConference.getNumberOfParticipants());
- verify(mMockTelephonyConnectionServiceProxy, times(2)).removeConnection(
- any(Connection.class));
reset(mMockTelephonyConnectionServiceProxy);
// Back to 2!
@@ -161,8 +160,6 @@
imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
Arrays.asList(participant1, participant2, participant3Disconnected));
assertEquals(2, imsConference.getNumberOfParticipants());
- verify(mMockTelephonyConnectionServiceProxy, times(1)).removeConnection(
- any(Connection.class));
reset(mMockTelephonyConnectionServiceProxy);
// Now remove it from another CEP update; should still be the same number of participants
@@ -170,8 +167,6 @@
imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
Arrays.asList(participant1, participant2));
assertEquals(2, imsConference.getNumberOfParticipants());
- verify(mMockTelephonyConnectionServiceProxy, never()).removeConnection(
- any(Connection.class));
verify(mMockTelephonyConnectionServiceProxy, never()).addExistingConnection(
any(PhoneAccountHandle.class), any(Connection.class),
any(Conference.class));
@@ -222,8 +217,6 @@
imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
Arrays.asList(participant1, participant2));
assertEquals(2, imsConference.getNumberOfParticipants());
- verify(mMockTelephonyConnectionServiceProxy, times(1)).removeConnection(
- any(Connection.class));
verify(mMockTelephonyConnectionServiceProxy, never()).addExistingConnection(
any(PhoneAccountHandle.class), any(Connection.class),
any(Conference.class));
@@ -280,8 +273,6 @@
imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
Arrays.asList(participant1, participant2Disconnected));
assertEquals(0, imsConference.getNumberOfParticipants());
- verify(mMockTelephonyConnectionServiceProxy, times(2)).removeConnection(
- any(Connection.class));
reset(mMockTelephonyConnectionServiceProxy);
// Pretend to merge someone else into the conference.
@@ -310,14 +301,14 @@
null /* phoneAccountHandle */, () -> true /* featureFlagProxy */);
final boolean[] isConferenceState = new boolean[1];
- Conference.Listener conferenceListener = new Conference.Listener() {
+ TelephonyConferenceBase.TelephonyConferenceListener conferenceListener =
+ new TelephonyConferenceBase.TelephonyConferenceListener() {
@Override
- public void onConferenceStateChanged(Conference c, boolean isConference) {
- super.onConferenceStateChanged(c, isConference);
- isConferenceState[0] = isConference;
+ public void onConferenceMembershipChanged(Connection connection) {
+ isConferenceState[0] = connection.getConference() != null;
}
};
- imsConference.addListener(conferenceListener);
+ imsConference.addTelephonyConferenceListener(conferenceListener);
ConferenceParticipant participant1 = new ConferenceParticipant(
Uri.parse("tel:6505551212"),
@@ -342,8 +333,6 @@
imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
Arrays.asList(participant1));
assertEquals(0, imsConference.getNumberOfParticipants());
- verify(mMockTelephonyConnectionServiceProxy, times(2)).removeConnection(
- any(Connection.class));
// Emulate a pre-disconnect conference event package; there will be zero participants.
imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
diff --git a/tests/src/com/android/services/telephony/TelephonyConferenceControllerTest.java b/tests/src/com/android/services/telephony/TelephonyConferenceControllerTest.java
index 4fc8c02..cfdc2fd 100644
--- a/tests/src/com/android/services/telephony/TelephonyConferenceControllerTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConferenceControllerTest.java
@@ -48,7 +48,7 @@
private TelephonyConnectionServiceProxy mMockTelephonyConnectionServiceProxy;
@Mock
- private Conference.Listener mMockListener;
+ private TelephonyConferenceBase.TelephonyConferenceListener mMockListener;
private TestTelephonyConnection mTestTelephonyConnectionA;
private TestTelephonyConnection mTestTelephonyConnectionB;
@@ -158,7 +158,7 @@
verify(mMockTelephonyConnectionServiceProxy).addConference(argumentCaptor.capture());
// add a listener to the added conference
- argumentCaptor.getValue().addListener(mMockListener);
+ argumentCaptor.getValue().addTelephonyConferenceListener(mMockListener);
verify(mMockListener, never()).onDestroyed(any(Conference.class));