aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames.cf Lin <jamescflin@google.com>2021-06-04 01:41:37 +0800
committerJames.cf Lin <jamescflin@google.com>2021-06-04 14:59:34 +0800
commit4b733da9db01754962d4e4c80040f762352978cb (patch)
tree6097c27a39388762ca04bddea053f5862f860005
parent3808616ef55e642e440f27c90892c11f8e4f4f4b (diff)
downloadims-4b733da9db01754962d4e4c80040f762352978cb.tar.gz
When the capability type is SIP OPTIONS, the PUBLISH STATE should be OK
Bug: 188447963 Test: atest -c CtsTelephonyTestCases:android.telephony.ims.cts.ImsServiceTest Change-Id: I2c7bb5fe471578e3442c4857b0678fd798a3191e
-rw-r--r--src/java/com/android/ims/rcs/uce/presence/publish/PublishControllerImpl.java114
-rw-r--r--src/java/com/android/ims/rcs/uce/presence/publish/PublishUtils.java15
-rw-r--r--tests/src/com/android/ims/rcs/uce/presence/publish/PublishControllerImplTest.java32
3 files changed, 150 insertions, 11 deletions
diff --git a/src/java/com/android/ims/rcs/uce/presence/publish/PublishControllerImpl.java b/src/java/com/android/ims/rcs/uce/presence/publish/PublishControllerImpl.java
index 9da4e4f8..e387ca9e 100644
--- a/src/java/com/android/ims/rcs/uce/presence/publish/PublishControllerImpl.java
+++ b/src/java/com/android/ims/rcs/uce/presence/publish/PublishControllerImpl.java
@@ -89,6 +89,8 @@ public class PublishControllerImpl implements PublishController {
private volatile RcsFeatureManager mRcsFeatureManager;
private final UceControllerCallback mUceCtrlCallback;
+ // The capability type that the device is using.
+ private @RcsImsCapabilityFlag int mCapabilityType;
// The device publish state
private @PublishState int mPublishState;
// The timestamp of updating the publish state
@@ -154,7 +156,8 @@ public class PublishControllerImpl implements PublishController {
}
private void initPublishController(Looper looper) {
- mPublishState = RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED;
+ mCapabilityType = PublishUtils.getCapabilityType(mContext, mSubId);
+ mPublishState = getInitialPublishState(mCapabilityType);
mPublishStateCallbacks = new RemoteCallbackList<>();
mPublishHandler = new PublishHandler(this, looper);
@@ -166,6 +169,26 @@ public class PublishControllerImpl implements PublishController {
// Turn on the listener to listen to the device changes.
mDeviceCapListener.initialize();
+
+ logd("initPublishController completed: capabilityType=" + mCapabilityType +
+ ", publishState=" + mPublishState);
+ }
+
+ /**
+ * Get the initial publish state according to the given capability type.
+ * <p>
+ * The default publish state is NOT_PUBLISH when the capability type is PRESENCE.
+ * The default publish state is OK when the capability type is SIP OPTIONS.
+ * Otherwise, the default initial value is ERROR.
+ */
+ private int getInitialPublishState(@RcsImsCapabilityFlag int capabilityType) {
+ if (capabilityType == RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE) {
+ return RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED;
+ } else if (capabilityType == RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE) {
+ return RcsUceAdapter.PUBLISH_STATE_OK;
+ } else {
+ return RcsUceAdapter.PUBLISH_STATE_OTHER_ERROR;
+ }
}
private void initPublishProcessor() {
@@ -573,14 +596,7 @@ public class PublishControllerImpl implements PublishController {
}
public void sendPublishMessage(@PublishTriggerType int type) {
- PublishControllerImpl publishCtrl = mPublishControllerRef.get();
- if (publishCtrl == null) return;
- if (publishCtrl.mIsDestroyedFlag) return;
-
- Message message = obtainMessage();
- message.what = MSG_REQUEST_PUBLISH;
- message.arg1 = type;
- sendMessage(message);
+ sendPublishMessage(type, 0L);
}
public void sendPublishMessage(@PublishTriggerType int type, long delay) {
@@ -588,6 +604,13 @@ public class PublishControllerImpl implements PublishController {
if (publishCtrl == null) return;
if (publishCtrl.mIsDestroyedFlag) return;
+ // Disallow publish if the PRESENCE PUBLISH is not enabled and this request is not
+ // triggered by the ImsService.
+ if (!publishCtrl.isPresencePublishEnabled() && type != PUBLISH_TRIGGER_SERVICE) {
+ publishCtrl.logd("sendPublishMessage: disallowed type=" + type);
+ return;
+ }
+
Message message = obtainMessage();
message.what = MSG_REQUEST_PUBLISH;
message.arg1 = type;
@@ -692,7 +715,8 @@ public class PublishControllerImpl implements PublishController {
// The first PUBLISH request is required to be triggered from the service.
if (!mReceivePublishFromService) {
- logd("isPublishRequestAllowed: Have not received the first PUBLISH from the service.");
+ logd("isPublishRequestAllowed: "
+ + "The first PUBLISH request from the server has not been received.");
return false;
}
@@ -713,6 +737,19 @@ public class PublishControllerImpl implements PublishController {
return true;
}
+ /**
+ * Check whether the PRESENCE PUBLISH should be enabled or not. It should be enabled only when
+ * the PRESENCE mechanism is supported.
+ */
+ private boolean isPresencePublishEnabled() {
+ synchronized (mPublishStateLock) {
+ return mCapabilityType == RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE;
+ }
+ }
+
+ /**
+ * Handle the RCS connected message. This method is called in the handler thread.
+ */
private void handleRcsConnectedMessage(RcsFeatureManager manager) {
if (mIsDestroyedFlag) return;
mRcsFeatureManager = manager;
@@ -721,15 +758,27 @@ public class PublishControllerImpl implements PublishController {
registerRcsAvailabilityChanged(manager);
}
+ /**
+ * Handle the RCS disconnected message. This method is called in the handler thread.
+ */
private void handleRcsDisconnectedMessage() {
if (mIsDestroyedFlag) return;
mRcsFeatureManager = null;
- onUnpublish();
mDeviceCapabilityInfo.updatePresenceCapable(false);
mDeviceCapListener.onRcsDisconnected();
mPublishProcessor.onRcsDisconnected();
+
+ // When the RCS is disconnected, update the publish state to NOT_PUBLISH if the PRESENCE
+ // PUBLISH is enabled.
+ if (isPresencePublishEnabled()) {
+ handlePublishStateChangedMessage(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED,
+ Instant.now(), null /*pidfXml*/);
+ }
}
+ /**
+ * Handle the Destroyed message. This method is called in the handler thread.
+ */
private void handleDestroyedMessage() {
mIsDestroyedFlag = true;
mDeviceCapabilityInfo.updatePresenceCapable(false);
@@ -768,8 +817,14 @@ public class PublishControllerImpl implements PublishController {
}
}
+ /**
+ * Handle the carrier config changed message. This method is called in the handler thread.
+ */
private void handleCarrierConfigChangedMessage() {
if (mIsDestroyedFlag) return;
+
+ updateCapabilityTypeAndPublishStateIfNeeded();
+
String[] newMap = getCarrierServiceDescriptionFeatureTagMap();
if (mDeviceCapabilityInfo.updateCapabilityRegistrationTrackerMap(newMap)) {
mPublishHandler.sendPublishMessage(
@@ -777,6 +832,37 @@ public class PublishControllerImpl implements PublishController {
}
}
+ /**
+ * Check whether the capability type has changed or not because of the carrier config changed.
+ * If the capability type has changed, the publish state also needs to be reinitialized.
+ * <p>
+ * This method is called in the handler thread.
+ */
+ private void updateCapabilityTypeAndPublishStateIfNeeded() {
+ synchronized (mPublishStateLock) {
+ int originalMechanism = mCapabilityType;
+ mCapabilityType = PublishUtils.getCapabilityType(mContext, mSubId);
+
+ // Return when the capability type has not changed.
+ if (originalMechanism == mCapabilityType) {
+ logd("updateCapTypeAndPublishStateIfNeeded: " +
+ "The capability type is not changed=" + mCapabilityType);
+ return;
+ }
+
+ // Reinitialize the publish state because the capability type has changed.
+ int updatedPublishState = getInitialPublishState(mCapabilityType);
+
+ logd("updateCapTypeAndPublishStateIfNeeded from " + originalMechanism +
+ " to " + mCapabilityType + ", new publish state=" + updatedPublishState);
+
+ // Update the publish state directly. Because this method is called in the
+ // handler thread already, the process of updating publish state does not need to be
+ // sent to the looper again.
+ handlePublishStateChangedMessage(updatedPublishState, Instant.now(), null /*pidfxml*/);
+ }
+ }
+
private String[] getCarrierServiceDescriptionFeatureTagMap() {
CarrierConfigManager manager = mContext.getSystemService(CarrierConfigManager.class);
PersistableBundle bundle = manager != null ? manager.getConfigForSubId(mSubId) :
@@ -899,6 +985,12 @@ public class PublishControllerImpl implements PublishController {
}
@VisibleForTesting
+ public void setCapabilityType(int type) {
+ mCapabilityType = type;
+ mPublishState = getInitialPublishState(mCapabilityType);
+ }
+
+ @VisibleForTesting
public void setPublishStateCallback(RemoteCallbackList<IRcsUcePublishStateCallback> list) {
mPublishStateCallbacks = list;
}
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 e412cc6d..ea1d11b9 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
@@ -20,6 +20,8 @@ import android.content.Context;
import android.net.Uri;
import android.telephony.PhoneNumberUtils;
import android.telephony.TelephonyManager;
+import android.telephony.ims.feature.RcsFeature.RcsImsCapabilities;
+import android.telephony.ims.feature.RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag;
import android.text.TextUtils;
import android.util.Log;
@@ -133,4 +135,17 @@ public class PublishUtils {
return telephonyManager.createForSubscriptionId(subId);
}
}
+
+ static @RcsImsCapabilityFlag int getCapabilityType(Context context, int subId) {
+ boolean isPresenceSupported = UceUtils.isPresenceSupported(context, subId);
+ boolean isSipOptionsSupported = UceUtils.isSipOptionsSupported(context, subId);
+ if (isPresenceSupported) {
+ return RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE;
+ } else if (isSipOptionsSupported) {
+ return RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE;
+ } else {
+ // Return NONE when neither OPTIONS nor PRESENCE is supported.
+ return RcsImsCapabilities.CAPABILITY_TYPE_NONE;
+ }
+ }
}
diff --git a/tests/src/com/android/ims/rcs/uce/presence/publish/PublishControllerImplTest.java b/tests/src/com/android/ims/rcs/uce/presence/publish/PublishControllerImplTest.java
index ba388104..b4c9b873 100644
--- a/tests/src/com/android/ims/rcs/uce/presence/publish/PublishControllerImplTest.java
+++ b/tests/src/com/android/ims/rcs/uce/presence/publish/PublishControllerImplTest.java
@@ -35,6 +35,7 @@ import android.os.RemoteCallbackList;
import android.telephony.ims.RcsUceAdapter;
import android.telephony.ims.aidl.IImsCapabilityCallback;
import android.telephony.ims.aidl.IRcsUcePublishStateCallback;
+import android.telephony.ims.feature.RcsFeature.RcsImsCapabilities;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
@@ -315,11 +316,42 @@ public class PublishControllerImplTest extends ImsTestBase {
assertFalse("still contained 555-555-1212: " + testString, result.contains("555-555-1212"));
}
+ @Test
+ @SmallTest
+ public void testNotPublishWhitSipOptions() throws Exception {
+ PublishControllerImpl publishController = createPublishController();
+ publishController.setCapabilityType(RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE);
+ doReturn(Optional.of(0L)).when(mPublishProcessor).getPublishingDelayTime();
+
+ // Trigger a publish request (VT changes)
+ PublishControllerCallback callback = publishController.getPublishControllerCallback();
+ callback.requestPublishFromInternal(PUBLISH_TRIGGER_VT_SETTING_CHANGE);
+ Handler handler = publishController.getPublishHandler();
+ waitForHandlerAction(handler, 1000);
+
+ // Verify it cannot be processed because the capability type is SIP OPTIONS and the publish
+ // request is triggered from device changed
+ verify(mPublishProcessor, never()).doPublish(PUBLISH_TRIGGER_VT_SETTING_CHANGE);
+
+ // Set the PRESENCE is capable
+ IImsCapabilityCallback RcsCapCallback = publishController.getRcsCapabilitiesCallback();
+ RcsCapCallback.onCapabilitiesStatusChanged(RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE);
+
+ // Trigger the PUBLISH request from the service.
+ publishController.requestPublishCapabilitiesFromService(
+ RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN);
+ waitForHandlerAction(handler, 1000);
+
+ // Verify the request which is from the service can be processed
+ verify(mPublishProcessor).doPublish(PublishController.PUBLISH_TRIGGER_SERVICE);
+ }
+
private PublishControllerImpl createPublishController() {
PublishControllerImpl publishController = new PublishControllerImpl(mContext, mSubId,
mUceCtrlCallback, Looper.getMainLooper(), mDeviceCapListenerFactory,
mPublishProcessorFactory);
publishController.setPublishStateCallback(mPublishStateCallbacks);
+ publishController.setCapabilityType(RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE);
return publishController;
}
}