[RCS] Integrate the PresencePublisher in UserCapabilityExchangeImpl
Implement the interface PresencePublisher which was called from PresencePublication
Bug: 139262111
Test: atest UserCapabilityExchangeImplTest
Change-Id: I6f0d1ec3eec3aadfbf493b44771ae176536f7e15
diff --git a/tests/src/com/android/TestContext.java b/tests/src/com/android/TestContext.java
index c190be9..b1c6923 100644
--- a/tests/src/com/android/TestContext.java
+++ b/tests/src/com/android/TestContext.java
@@ -20,6 +20,7 @@
import static org.mockito.Mockito.doReturn;
import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -29,6 +30,7 @@
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.telephony.ims.ImsManager;
import android.test.mock.MockContext;
import org.mockito.Mock;
@@ -42,6 +44,7 @@
@Mock TelecomManager mMockTelecomManager;
@Mock TelephonyManager mMockTelephonyManager;
@Mock SubscriptionManager mMockSubscriptionManager;
+ @Mock ImsManager mMockImsManager;
private PersistableBundle mCarrierConfig = new PersistableBundle();
@@ -89,6 +92,11 @@
}
@Override
+ public ContentResolver getContentResolver() {
+ return null;
+ }
+
+ @Override
public Object getSystemService(String name) {
switch (name) {
case (Context.CARRIER_CONFIG_SERVICE) : {
@@ -103,6 +111,9 @@
case (Context.TELEPHONY_SUBSCRIPTION_SERVICE) : {
return mMockSubscriptionManager;
}
+ case(Context.TELEPHONY_IMS_SERVICE) : {
+ return mMockImsManager;
+ }
}
return null;
}
diff --git a/tests/src/com/android/services/telephony/rcs/UserCapabilityExchangeImplTest.java b/tests/src/com/android/services/telephony/rcs/UserCapabilityExchangeImplTest.java
new file mode 100644
index 0000000..2457d28
--- /dev/null
+++ b/tests/src/com/android/services/telephony/rcs/UserCapabilityExchangeImplTest.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2020 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.services.telephony.rcs;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.net.Uri;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.RemoteCallbackList;
+import android.telephony.ims.ImsManager;
+import android.telephony.ims.ImsMmTelManager;
+import android.telephony.ims.RcsContactUceCapability;
+import android.telephony.ims.RegistrationManager;
+import android.telephony.ims.aidl.IRcsUcePublishStateCallback;
+import android.telephony.ims.stub.RcsCapabilityExchange;
+import android.telephony.ims.stub.RcsPresenceExchangeImplBase;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.TelephonyTestBase;
+import com.android.ims.RcsFeatureManager;
+import com.android.ims.RcsFeatureManager.RcsFeatureCallbacks;
+import com.android.ims.ResultCode;
+import com.android.service.ims.presence.PresenceBase;
+import com.android.service.ims.presence.PresencePublication;
+import com.android.service.ims.presence.PresencePublisher;
+import com.android.service.ims.presence.PresenceSubscriber;
+import com.android.service.ims.presence.SubscribePublisher;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+
+import java.util.concurrent.Executor;
+
+@RunWith(AndroidJUnit4.class)
+public class UserCapabilityExchangeImplTest extends TelephonyTestBase {
+
+ private int mSlotId = 0;
+ private int mSubId = 1;
+ private int mUpdatedSubId = 2;
+
+ @Captor ArgumentCaptor<IRcsUcePublishStateCallback> mPublishStateCallbacksCaptor;
+
+ @Mock PresencePublication mPresencePublication;
+ @Mock PresenceSubscriber mPresenceSubscriber;
+ @Mock RcsFeatureManager mRcsFeatureManager;
+ @Mock ImsMmTelManager mImsMmTelManager;
+ @Mock RemoteCallbackList<IRcsUcePublishStateCallback> mPublishStateCallbacks;
+
+ private Looper mLooper;
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+
+ ImsManager imsManager =
+ (ImsManager) mContext.getSystemService(Context.TELEPHONY_IMS_SERVICE);
+ when(imsManager.getImsMmTelManager(mSubId)).thenReturn(mImsMmTelManager);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+
+ if (mLooper != null) {
+ mLooper.quit();
+ mLooper = null;
+ }
+ }
+
+ @Test
+ public void testServiceConnected() throws Exception {
+ UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
+ uceImpl.onRcsConnected(mRcsFeatureManager);
+
+ verify(mRcsFeatureManager).addFeatureListenerCallback(any(RcsFeatureCallbacks.class));
+ verify(mPresencePublication).updatePresencePublisher(any(PresencePublisher.class));
+ verify(mPresenceSubscriber).updatePresenceSubscriber(any(SubscribePublisher.class));
+ }
+
+ @Test
+ public void testServiceDisconnected() throws Exception {
+ UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
+ uceImpl.onRcsDisconnected();
+
+ verify(mPresencePublication).removePresencePublisher();
+ verify(mPresenceSubscriber).removePresenceSubscriber();
+ }
+
+ @Test
+ public void testSubscriptionUpdated() throws Exception {
+ UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
+ uceImpl.onAssociatedSubscriptionUpdated(mUpdatedSubId);
+
+ verify(mImsMmTelManager).registerImsRegistrationCallback(any(Executor.class),
+ any(RegistrationManager.RegistrationCallback.class));
+ verify(mImsMmTelManager).registerMmTelCapabilityCallback(any(Executor.class),
+ any(ImsMmTelManager.CapabilityCallback.class));
+ verify(mPresencePublication).handleAssociatedSubscriptionChanged(mUpdatedSubId);
+ verify(mPresenceSubscriber).handleAssociatedSubscriptionChanged(mUpdatedSubId);
+ }
+
+ @Test
+ public void testUcePublishStateRetrieval() throws Exception {
+ UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
+ uceImpl.getUcePublishState();
+
+ verify(mPresencePublication).getPublishState();
+ }
+
+ @Test
+ public void testRegisterPublishStateCallbacks() throws Exception {
+ UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
+ uceImpl.registerPublishStateCallback(any(IRcsUcePublishStateCallback.class));
+ verify(mPublishStateCallbacks).register(mPublishStateCallbacksCaptor.capture());
+ }
+
+ @Test
+ public void testOnNotifyUpdateCapabilities() throws Exception {
+ UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
+ uceImpl.onRcsConnected(mRcsFeatureManager);
+
+ int triggerType = RcsPresenceExchangeImplBase.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN;
+ uceImpl.mRcsFeatureCallback.onNotifyUpdateCapabilities(triggerType);
+ waitForMs(1000);
+
+ verify(mPresencePublication).onStackPublishRequested(triggerType);
+ }
+
+ @Test
+ public void testRequestPublicationWithSuccessfulResponse() throws Exception {
+ int taskId = 1;
+ int sipResponse = 200;
+ Uri contact = Uri.fromParts("sip", "test", null);
+ RcsContactUceCapability.Builder builder = new RcsContactUceCapability.Builder(contact);
+ RcsContactUceCapability capability = builder.build();
+
+ UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
+ uceImpl.onRcsConnected(mRcsFeatureManager);
+
+ doAnswer(invocation -> {
+ uceImpl.mRcsFeatureCallback.onCommandUpdate(RcsCapabilityExchange.COMMAND_CODE_SUCCESS,
+ taskId);
+ uceImpl.mRcsFeatureCallback.onNetworkResponse(sipResponse, null, taskId);
+ return null;
+ }).when(mRcsFeatureManager).requestPublication(capability, taskId);
+
+ // Request publication
+ int result = uceImpl.requestPublication(capability, contact.toString(), taskId);
+
+ assertEquals(ResultCode.SUCCESS, result);
+ verify(mPresencePublication).onCommandStatusUpdated(taskId, taskId, ResultCode.SUCCESS);
+ verify(mPresencePublication).onSipResponse(taskId, sipResponse, null);
+ }
+
+ @Test
+ public void testRequestPublicationWithFailedResponse() throws Exception {
+ int taskId = 1;
+ Uri contact = Uri.fromParts("sip", "test", null);
+ RcsContactUceCapability.Builder builder = new RcsContactUceCapability.Builder(contact);
+ RcsContactUceCapability capability = builder.build();
+
+ UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
+ uceImpl.onRcsConnected(mRcsFeatureManager);
+
+ doAnswer(invocation -> {
+ uceImpl.mRcsFeatureCallback.onCommandUpdate(
+ RcsCapabilityExchange.COMMAND_CODE_GENERIC_FAILURE, taskId);
+ return null;
+ }).when(mRcsFeatureManager).requestPublication(capability, taskId);
+
+ // Request publication
+ int result = uceImpl.requestPublication(capability, contact.toString(), taskId);
+
+ assertEquals(ResultCode.SUCCESS, result);
+ verify(mPresencePublication).onCommandStatusUpdated(taskId, taskId,
+ ResultCode.PUBLISH_GENERIC_FAILURE);
+ }
+
+ @Test
+ public void testUpdatePublisherState() throws Exception {
+ IRcsUcePublishStateCallback callback = Mockito.mock(IRcsUcePublishStateCallback.class);
+ doAnswer(invocation -> {
+ callback.onPublishStateChanged(anyInt());
+ return null;
+ }).when(mPublishStateCallbacks).broadcast(any());
+
+ UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
+ uceImpl.onRcsConnected(mRcsFeatureManager);
+ uceImpl.registerPublishStateCallback(callback);
+ uceImpl.updatePublisherState(PresenceBase.PUBLISH_STATE_200_OK);
+
+ assertEquals(PresenceBase.PUBLISH_STATE_200_OK, uceImpl.getPublisherState());
+ verify(callback).onPublishStateChanged(anyInt());
+ }
+
+ @Test
+ public void testUnpublish() throws Exception {
+ IRcsUcePublishStateCallback callback = Mockito.mock(IRcsUcePublishStateCallback.class);
+ doAnswer(invocation -> {
+ callback.onPublishStateChanged(anyInt());
+ return null;
+ }).when(mPublishStateCallbacks).broadcast(any());
+
+ UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
+ uceImpl.onRcsConnected(mRcsFeatureManager);
+ uceImpl.mRcsFeatureCallback.onUnpublish();
+ waitForMs(1000);
+
+ assertEquals(PresenceBase.PUBLISH_STATE_NOT_PUBLISHED, uceImpl.getPublisherState());
+ verify(callback).onPublishStateChanged(anyInt());
+ }
+
+ private UserCapabilityExchangeImpl createUserCapabilityExchangeImpl() throws Exception {
+ HandlerThread handlerThread = new HandlerThread("UceImplHandlerThread");
+ handlerThread.start();
+ mLooper = handlerThread.getLooper();
+ UserCapabilityExchangeImpl uceImpl = new UserCapabilityExchangeImpl(mContext, mSlotId,
+ mSubId, mLooper, mPresencePublication, mPresenceSubscriber,
+ mPublishStateCallbacks);
+ verify(mPresencePublication).handleAssociatedSubscriptionChanged(1);
+ verify(mPresenceSubscriber).handleAssociatedSubscriptionChanged(1);
+ waitForHandlerAction(uceImpl.getHandler(), 1000);
+ verify(mImsMmTelManager, atLeast(1)).registerImsRegistrationCallback(
+ any(Executor.class), any(RegistrationManager.RegistrationCallback.class));
+ verify(mContext).registerReceiver(any(), any());
+ return uceImpl;
+ }
+}