aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-05-07 21:07:05 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-05-07 21:07:05 +0000
commit5fdaf4ec937d8d8a5de5943090067aac41157c14 (patch)
tree69b7396411f5e69e690910c73bf9c0d3c64c4676
parentf8ea84388153fb5282ddfa25182a641f4c4aa800 (diff)
parent04dfd01b0b54ea9755e4187cccafe183142a1a61 (diff)
downloadims-5fdaf4ec937d8d8a5de5943090067aac41157c14.tar.gz
Snap for 8557511 from 04dfd01b0b54ea9755e4187cccafe183142a1a61 to tm-d1-release
Change-Id: I4711b6ce56daa12f1506eb282c26011fde8c5e32
-rw-r--r--src/java/com/android/ims/rcs/uce/presence/publish/DeviceCapabilityInfo.java34
-rw-r--r--src/java/com/android/ims/rcs/uce/presence/publish/PublishUtils.java75
-rw-r--r--src/java/com/android/ims/rcs/uce/util/UceUtils.java16
-rw-r--r--tests/src/com/android/ims/rcs/uce/presence/publish/DeviceCapabilityInfoTest.java149
4 files changed, 261 insertions, 13 deletions
diff --git a/src/java/com/android/ims/rcs/uce/presence/publish/DeviceCapabilityInfo.java b/src/java/com/android/ims/rcs/uce/presence/publish/DeviceCapabilityInfo.java
index 7fcb1ff7..dc794331 100644
--- a/src/java/com/android/ims/rcs/uce/presence/publish/DeviceCapabilityInfo.java
+++ b/src/java/com/android/ims/rcs/uce/presence/publish/DeviceCapabilityInfo.java
@@ -20,6 +20,7 @@ import static android.telephony.ims.RcsContactUceCapability.SOURCE_TYPE_CACHED;
import android.content.Context;
import android.net.Uri;
+import android.telecom.PhoneAccount;
import android.telecom.TelecomManager;
import android.telephony.AccessNetworkConstants;
import android.telephony.ims.ImsRegistrationAttributes;
@@ -273,10 +274,33 @@ public class DeviceCapabilityInfo {
}
/**
- * Get the IMS associated URI. It will first get the uri of MMTEL if it is not empty, otherwise
- * it will try to get the uri of RCS. The null will be returned if both MMTEL and RCS are empty.
+ * Get the first URI from the "p-associated-uri" header included in the IMS registration
+ * response.
+ * @param preferTelUri If {@code true}, prefer returning the first TEL URI. If no TEL
+ * URIs exist, this method will still return the preferred (first) SIP URI
+ * in the header. If {@code false}, we will return the first URI
+ * in the "p-associated-uri" header, independent of the URI scheme.
*/
- public synchronized Uri getImsAssociatedUri() {
+ public synchronized Uri getImsAssociatedUri(boolean preferTelUri) {
+ if (preferTelUri) {
+ if (!mRcsAssociatedUris.isEmpty()) {
+ for (Uri rcsAssociatedUri : mRcsAssociatedUris) {
+ if (PhoneAccount.SCHEME_TEL.equalsIgnoreCase(rcsAssociatedUri.getScheme())) {
+ return rcsAssociatedUri;
+ }
+ }
+ }
+ if (!mMmtelAssociatedUris.isEmpty()) {
+ for (Uri mmtelAssociatedUri : mMmtelAssociatedUris) {
+ if (PhoneAccount.SCHEME_TEL.equalsIgnoreCase(mmtelAssociatedUri.getScheme())) {
+ return mmtelAssociatedUri;
+ }
+ }
+ }
+ }
+
+ // Either we have not found a TEL URI or we do not prefer TEL URIs. Get the first URI from
+ // p-associated-uri list.
if (!mRcsAssociatedUris.isEmpty()) {
return mRcsAssociatedUris.get(0);
} else if (!mMmtelAssociatedUris.isEmpty()) {
@@ -473,7 +497,7 @@ public class DeviceCapabilityInfo {
// Get the device's capabilities with the PRESENCE mechanism.
private RcsContactUceCapability getPresenceCapabilities(Context context) {
- Uri uri = PublishUtils.getDeviceContactUri(context, mSubId, this);
+ Uri uri = PublishUtils.getDeviceContactUri(context, mSubId, this, true);
if (uri == null) {
logw("getPresenceCapabilities: uri is empty");
return null;
@@ -534,7 +558,7 @@ public class DeviceCapabilityInfo {
// Get the device's capabilities with the OPTIONS mechanism.
private RcsContactUceCapability getOptionsCapabilities(Context context) {
- Uri uri = PublishUtils.getDeviceContactUri(context, mSubId, this);
+ Uri uri = PublishUtils.getDeviceContactUri(context, mSubId, this, false);
if (uri == null) {
logw("getOptionsCapabilities: uri is empty");
return null;
diff --git a/src/java/com/android/ims/rcs/uce/presence/publish/PublishUtils.java b/src/java/com/android/ims/rcs/uce/presence/publish/PublishUtils.java
index ea1d11b9..1a67a40a 100644
--- a/src/java/com/android/ims/rcs/uce/presence/publish/PublishUtils.java
+++ b/src/java/com/android/ims/rcs/uce/presence/publish/PublishUtils.java
@@ -18,6 +18,7 @@ package com.android.ims.rcs.uce.presence.publish;
import android.content.Context;
import android.net.Uri;
+import android.telecom.PhoneAccount;
import android.telephony.PhoneNumberUtils;
import android.telephony.TelephonyManager;
import android.telephony.ims.feature.RcsFeature.RcsImsCapabilities;
@@ -25,6 +26,9 @@ import android.telephony.ims.feature.RcsFeature.RcsImsCapabilities.RcsImsCapabil
import android.text.TextUtils;
import android.util.Log;
+import com.android.i18n.phonenumbers.NumberParseException;
+import com.android.i18n.phonenumbers.PhoneNumberUtil;
+import com.android.i18n.phonenumbers.Phonenumber;
import com.android.ims.rcs.uce.util.UceUtils;
import java.util.Arrays;
@@ -39,29 +43,49 @@ public class PublishUtils {
private static final String SCHEME_TEL = "tel";
private static final String DOMAIN_SEPARATOR = "@";
+ /**
+ * @return the contact URI of this device for either a PRESENCE or OPTIONS capabilities request.
+ * We will first try to use the IMS service associated URIs from the p-associated-uri header
+ * in the IMS registration response. If this is not available, we will fall back to using the
+ * SIM card information to generate the URI.
+ */
public static Uri getDeviceContactUri(Context context, int subId,
- DeviceCapabilityInfo deviceCap) {
- // Get the uri from the IMS associated URI which is provided by the IMS service.
- Uri contactUri = deviceCap.getImsAssociatedUri();
+ DeviceCapabilityInfo deviceCap, boolean isForPresence) {
+ boolean preferTelUri = false;
+ if (isForPresence) {
+ preferTelUri = UceUtils.isTelUriForPidfXmlEnabled(context, subId);
+ }
+ // Get the uri from the IMS p-associated-uri header which is provided by the IMS service.
+ Uri contactUri = deviceCap.getImsAssociatedUri(preferTelUri);
if (contactUri != null) {
- Log.d(LOG_TAG, "getDeviceContactUri: ims associated uri");
+ Uri convertedUri = preferTelUri ? getConvertedTelUri(context, contactUri) : contactUri;
+ Log.d(LOG_TAG, "getDeviceContactUri: returning "
+ + (contactUri.equals(convertedUri) ? "found" : "converted")
+ + " ims associated uri");
return contactUri;
}
+ // No IMS service provided URIs, so generate the contact uri from ISIM.
TelephonyManager telephonyManager = getTelephonyManager(context, subId);
if (telephonyManager == null) {
Log.w(LOG_TAG, "getDeviceContactUri: TelephonyManager is null");
return null;
}
-
- // Get the contact uri from ISIM.
contactUri = getContactUriFromIsim(telephonyManager);
if (contactUri != null) {
Log.d(LOG_TAG, "getDeviceContactUri: impu");
- return contactUri;
+ if (preferTelUri) {
+ return getConvertedTelUri(context, contactUri);
+ } else {
+ return contactUri;
+ }
} else {
Log.d(LOG_TAG, "getDeviceContactUri: line number");
- return getContactUriFromLine1Number(telephonyManager);
+ if (preferTelUri) {
+ return getConvertedTelUri(context, getContactUriFromLine1Number(telephonyManager));
+ } else {
+ return getContactUriFromLine1Number(telephonyManager);
+ }
}
}
@@ -136,6 +160,41 @@ public class PublishUtils {
}
}
+ /**
+ * @return a TEL URI version of the contact URI if given a SIP URI. If given a TEL URI, this
+ * method will return the same value given.
+ */
+ private static Uri getConvertedTelUri(Context context, Uri contactUri) {
+ if (contactUri == null) {
+ return null;
+ }
+ if (contactUri.getScheme().equalsIgnoreCase(SCHEME_SIP)) {
+ TelephonyManager manager = context.getSystemService(TelephonyManager.class);
+ if (manager.getIsimDomain() == null) {
+ return contactUri;
+ }
+
+ String numbers = contactUri.getSchemeSpecificPart();
+ String[] numberParts = numbers.split("[@;:]");
+ String number = numberParts[0];
+
+ String simCountryIso = manager.getSimCountryIso();
+ if (!TextUtils.isEmpty(simCountryIso)) {
+ simCountryIso = simCountryIso.toUpperCase();
+ PhoneNumberUtil util = PhoneNumberUtil.getInstance();
+ try {
+ Phonenumber.PhoneNumber phoneNumber = util.parse(number, simCountryIso);
+ number = util.format(phoneNumber, PhoneNumberUtil.PhoneNumberFormat.E164);
+ String telUri = SCHEME_TEL + ":" + number;
+ contactUri = Uri.parse(telUri);
+ } catch (NumberParseException e) {
+ Log.w(LOG_TAG, "formatNumber: could not format " + number + ", error: " + e);
+ }
+ }
+ }
+ return contactUri;
+ }
+
static @RcsImsCapabilityFlag int getCapabilityType(Context context, int subId) {
boolean isPresenceSupported = UceUtils.isPresenceSupported(context, subId);
boolean isSipOptionsSupported = UceUtils.isSipOptionsSupported(context, subId);
diff --git a/src/java/com/android/ims/rcs/uce/util/UceUtils.java b/src/java/com/android/ims/rcs/uce/util/UceUtils.java
index 58796983..c5f2b122 100644
--- a/src/java/com/android/ims/rcs/uce/util/UceUtils.java
+++ b/src/java/com/android/ims/rcs/uce/util/UceUtils.java
@@ -210,6 +210,22 @@ public class UceUtils {
}
/**
+ * Check whether tel uri should be used for pidf xml
+ */
+ public static boolean isTelUriForPidfXmlEnabled(Context context, int subId) {
+ CarrierConfigManager configManager = context.getSystemService(CarrierConfigManager.class);
+ if (configManager == null) {
+ return false;
+ }
+ PersistableBundle config = configManager.getConfigForSubId(subId);
+ if (config == null) {
+ return false;
+ }
+ return config.getBoolean(
+ CarrierConfigManager.Ims.KEY_USE_TEL_URI_FOR_PIDF_XML_BOOL);
+ }
+
+ /**
* Get the minimum time that allow two PUBLISH requests can be executed continuously.
*
* @param subId The subscribe ID
diff --git a/tests/src/com/android/ims/rcs/uce/presence/publish/DeviceCapabilityInfoTest.java b/tests/src/com/android/ims/rcs/uce/presence/publish/DeviceCapabilityInfoTest.java
new file mode 100644
index 00000000..c977a080
--- /dev/null
+++ b/tests/src/com/android/ims/rcs/uce/presence/publish/DeviceCapabilityInfoTest.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2022 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.ims.rcs.uce.presence.publish;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import android.net.Uri;
+import android.telecom.PhoneAccount;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.ims.ImsTestBase;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+
+@RunWith(AndroidJUnit4.class)
+public class DeviceCapabilityInfoTest extends ImsTestBase {
+
+ int mSubId = 1;
+
+ String sipNumber = "123456789";
+ String telNumber = "987654321";
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ @Test
+ @SmallTest
+ public void testGetImsAssociatedUriWithoutPreferTelUri() throws Exception {
+ DeviceCapabilityInfo deviceCapInfo = createDeviceCapabilityInfo();
+
+ Uri[] uris = new Uri[2];
+ uris[0] = Uri.fromParts(PhoneAccount.SCHEME_SIP, sipNumber, null);
+ uris[1] = Uri.fromParts(PhoneAccount.SCHEME_TEL, telNumber, null);
+
+ // When stored in the order of SIP, TEL URI, check whether the SIP URI saved at
+ // the beginning is retrieved.
+ deviceCapInfo.updateRcsAssociatedUri(uris);
+ Uri outUri = deviceCapInfo.getImsAssociatedUri(false);
+
+ String numbers = outUri.getSchemeSpecificPart();
+ String[] numberParts = numbers.split("[@;:]");
+ String number = numberParts[0];
+
+ assertEquals(number, sipNumber);
+
+ // When stored in the order of TEL, SIP URI, check whether the TEL URI saved at
+ // the beginning is retrieved.
+ deviceCapInfo = createDeviceCapabilityInfo();
+
+ uris[0] = Uri.fromParts(PhoneAccount.SCHEME_TEL, telNumber, null);
+ uris[1] = Uri.fromParts(PhoneAccount.SCHEME_SIP, sipNumber, null);
+
+ deviceCapInfo.updateRcsAssociatedUri(uris);
+ outUri = deviceCapInfo.getImsAssociatedUri(false);
+
+ numbers = outUri.getSchemeSpecificPart();
+ numberParts = numbers.split("[@;:]");
+ number = numberParts[0];
+
+ assertEquals(number, telNumber);
+ }
+
+ @Test
+ @SmallTest
+ public void testGetImsAssociatedUriWithPreferTelUri() throws Exception {
+ DeviceCapabilityInfo deviceCapInfo = createDeviceCapabilityInfo();
+
+ Uri[] uris = new Uri[2];
+ uris[0] = Uri.fromParts(PhoneAccount.SCHEME_SIP, sipNumber, null);
+ uris[1] = Uri.fromParts(PhoneAccount.SCHEME_TEL, telNumber, null);
+
+ // Check whether TEL URI is returned when preferTelUri is true even if SIP and TEL URI
+ // are in the order.
+ deviceCapInfo.updateRcsAssociatedUri(uris);
+ Uri outUri = deviceCapInfo.getImsAssociatedUri(true);
+
+ String numbers = outUri.getSchemeSpecificPart();
+ String[] numberParts = numbers.split("[@;:]");
+ String number = numberParts[0];
+
+ assertEquals(number, telNumber);
+
+ // If preferTelUri is true, check if a TEL URI is returned.
+ deviceCapInfo = createDeviceCapabilityInfo();
+
+ uris[0] = Uri.fromParts(PhoneAccount.SCHEME_TEL, telNumber, null);
+ uris[1] = Uri.fromParts(PhoneAccount.SCHEME_SIP, sipNumber, null);
+
+ deviceCapInfo.updateRcsAssociatedUri(uris);
+ outUri = deviceCapInfo.getImsAssociatedUri(true);
+
+ numbers = outUri.getSchemeSpecificPart();
+ numberParts = numbers.split("[@;:]");
+ number = numberParts[0];
+
+ assertEquals(number, telNumber);
+
+ // If there is only SIP URI, this method will still return a SIP URI, since there are no TEL
+ // URIs found in the list.
+ deviceCapInfo = createDeviceCapabilityInfo();
+
+ uris[0] = Uri.fromParts(PhoneAccount.SCHEME_SIP, telNumber, null);
+ uris[1] = Uri.fromParts(PhoneAccount.SCHEME_SIP, sipNumber, null);
+
+ deviceCapInfo.updateRcsAssociatedUri(uris);
+ outUri = deviceCapInfo.getImsAssociatedUri(true);
+
+ numbers = outUri.getSchemeSpecificPart();
+ numberParts = numbers.split("[@;:]");
+ number = numberParts[0];
+
+ assertEquals(number, telNumber);
+
+ }
+
+ private DeviceCapabilityInfo createDeviceCapabilityInfo() {
+ DeviceCapabilityInfo deviceCapInfo = new DeviceCapabilityInfo(mSubId, null);
+ return deviceCapInfo;
+ }
+
+} \ No newline at end of file