• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.ims.rcs.uce.presence.publish;
18 
19 import static android.telephony.ims.RcsContactPresenceTuple.TUPLE_BASIC_STATUS_OPEN;
20 
21 import static org.mockito.ArgumentMatchers.any;
22 import static org.mockito.ArgumentMatchers.anyInt;
23 import static org.mockito.ArgumentMatchers.anyLong;
24 import static org.mockito.ArgumentMatchers.eq;
25 import static org.mockito.Mockito.doReturn;
26 import static org.mockito.Mockito.never;
27 import static org.mockito.Mockito.verify;
28 
29 import android.content.Context;
30 import android.net.Uri;
31 import android.telephony.ims.RcsContactPresenceTuple;
32 import android.telephony.ims.RcsContactUceCapability;
33 import android.telephony.ims.SipDetails;
34 
35 import androidx.test.ext.junit.runners.AndroidJUnit4;
36 import androidx.test.filters.SmallTest;
37 
38 import com.android.ims.ImsTestBase;
39 import com.android.ims.RcsFeatureManager;
40 import com.android.ims.rcs.uce.UceStatsWriter;
41 import com.android.ims.rcs.uce.presence.publish.PublishController.PublishControllerCallback;
42 
43 import org.junit.After;
44 import org.junit.Before;
45 import org.junit.Test;
46 import org.junit.runner.RunWith;
47 import org.mockito.Mock;
48 
49 import java.time.Instant;
50 import java.util.Optional;
51 @RunWith(AndroidJUnit4.class)
52 public class PublishProcessorTest extends ImsTestBase {
53 
54     @Mock RcsFeatureManager mRcsFeatureManager;
55     @Mock DeviceCapabilityInfo mDeviceCapabilities;
56     @Mock PublishControllerCallback mPublishCtrlCallback;
57     @Mock PublishProcessorState mProcessorState;
58     @Mock PublishRequestResponse mResponseCallback;
59     @Mock UceStatsWriter mUceStatsWriter;
60 
61     private int mSub = 1;
62     private long mTaskId = 1L;
63 
64     public static class TestPublishProcessor extends PublishProcessor {
TestPublishProcessor(Context context, int subId, DeviceCapabilityInfo capabilityInfo, PublishControllerCallback publishCtrlCallback, UceStatsWriter instance)65         public TestPublishProcessor(Context context, int subId,
66                 DeviceCapabilityInfo capabilityInfo,
67                 PublishControllerCallback publishCtrlCallback,
68                 UceStatsWriter instance) {
69             super(context, subId, capabilityInfo, publishCtrlCallback, instance);
70         }
71 
72         @Override
isEabProvisioned()73         protected boolean isEabProvisioned() {
74             return true;
75         }
76     }
77 
78     @Before
setUp()79     public void setUp() throws Exception {
80         super.setUp();
81         doReturn(true).when(mProcessorState).isPublishAllowedAtThisTime();
82         doReturn(mTaskId).when(mProcessorState).getCurrentTaskId();
83 
84         doReturn(true).when(mDeviceCapabilities).isImsRegistered();
85         RcsContactUceCapability capability = getRcsContactUceCapability();
86         doReturn(capability).when(mDeviceCapabilities).getChangedPresenceCapability(any());
87         doReturn(capability).when(mDeviceCapabilities).getDeviceCapabilities(anyInt(), any());
88 
89         doReturn(mTaskId).when(mResponseCallback).getTaskId();
90     }
91 
92     @After
tearDown()93     public void tearDown() throws Exception {
94         super.tearDown();
95     }
96 
97     @Test
98     @SmallTest
testDoPublish()99     public void testDoPublish() throws Exception {
100         PublishProcessor publishProcessor = getPublishProcessor();
101 
102         publishProcessor.doPublish(PublishController.PUBLISH_TRIGGER_SERVICE);
103 
104         verify(mDeviceCapabilities).getDeviceCapabilities(anyInt(), any());
105         verify(mProcessorState).setPublishingFlag(true);
106         verify(mRcsFeatureManager).requestPublication(any(), any());
107         verify(mPublishCtrlCallback).setupRequestCanceledTimer(anyLong(), anyLong());
108         verify(mPublishCtrlCallback).notifyPendingPublishRequest();
109     }
110 
111     @Test
112     @SmallTest
testPublishWithoutResetRetryCount()113     public void testPublishWithoutResetRetryCount() throws Exception {
114         PublishProcessor publishProcessor = getPublishProcessor();
115 
116         publishProcessor.doPublish(PublishController.PUBLISH_TRIGGER_RETRY);
117         verify(mDeviceCapabilities).getChangedPresenceCapability(any());
118         verify(mProcessorState, never()).resetRetryCount();
119     }
120 
121     @Test
122     @SmallTest
testNotPublishWhenImsNotRegistered()123     public void testNotPublishWhenImsNotRegistered() throws Exception {
124         doReturn(false).when(mDeviceCapabilities).isImsRegistered();
125         PublishProcessor publishProcessor = getPublishProcessor();
126 
127         publishProcessor.doPublish(PublishController.PUBLISH_TRIGGER_RETRY);
128 
129         verify(mRcsFeatureManager, never()).requestPublication(any(), any());
130     }
131 
132     @Test
133     @SmallTest
testNotPublishWhenReachMaximumRetries()134     public void testNotPublishWhenReachMaximumRetries() throws Exception {
135         doReturn(true).when(mProcessorState).isPublishingNow();
136         doReturn(mTaskId).when(mProcessorState).getCurrentTaskId();
137         doReturn(mTaskId).when(mResponseCallback).getTaskId();
138         doReturn(true).when(mResponseCallback).needRetry();
139         doReturn(true).when(mProcessorState).isReachMaximumRetries();
140         PublishProcessor publishProcessor = getPublishProcessor();
141 
142         publishProcessor.onNetworkResponse(mResponseCallback);
143 
144         verify(mPublishCtrlCallback).updatePublishRequestResult(anyInt(), any(), any(), eq(null));
145         verify(mResponseCallback).onDestroy();
146         verify(mProcessorState).setPublishingFlag(false);
147         verify(mPublishCtrlCallback).clearRequestCanceledTimer();
148     }
149 
150     @Test
151     @SmallTest
testNotPublishWhenCurrentTimeNotAllowed()152     public void testNotPublishWhenCurrentTimeNotAllowed() throws Exception {
153         doReturn(false).when(mProcessorState).isPublishAllowedAtThisTime();
154         PublishProcessor publishProcessor = getPublishProcessor();
155 
156         publishProcessor.doPublish(PublishController.PUBLISH_TRIGGER_RETRY);
157 
158         verify(mPublishCtrlCallback).requestPublishFromInternal(
159                 eq(PublishController.PUBLISH_TRIGGER_RETRY));
160         verify(mRcsFeatureManager, never()).requestPublication(any(), any());
161     }
162 
163     @Test
164     @SmallTest
testCommandErrorWithRetry()165     public void testCommandErrorWithRetry() throws Exception {
166         doReturn(true).when(mProcessorState).isPublishingNow();
167         doReturn(mTaskId).when(mProcessorState).getCurrentTaskId();
168         doReturn(mTaskId).when(mResponseCallback).getTaskId();
169         doReturn(true).when(mResponseCallback).needRetry();
170         doReturn(Optional.of(10)).when(mResponseCallback).getCmdErrorCode();
171 
172         PublishProcessor publishProcessor = getPublishProcessor();
173 
174         publishProcessor.onCommandError(mResponseCallback);
175 
176         verify(mDeviceCapabilities).setPresencePublishResult(false);
177         verify(mProcessorState).increaseRetryCount();
178         verify(mPublishCtrlCallback).requestPublishFromInternal(
179                 eq(PublishController.PUBLISH_TRIGGER_RETRY));
180         verify(mResponseCallback).onDestroy();
181         verify(mProcessorState).setPublishingFlag(false);
182         verify(mPublishCtrlCallback).clearRequestCanceledTimer();
183         verify(mUceStatsWriter).setUceEvent(eq(mSub), eq(UceStatsWriter.PUBLISH_EVENT), eq(true),
184                 eq(10), eq(0));
185     }
186 
187     @Test
188     @SmallTest
testCommandErrorWithoutRetry()189     public void testCommandErrorWithoutRetry() throws Exception {
190         doReturn(true).when(mProcessorState).isPublishingNow();
191         doReturn(mTaskId).when(mProcessorState).getCurrentTaskId();
192         doReturn(mTaskId).when(mResponseCallback).getTaskId();
193         doReturn(false).when(mResponseCallback).needRetry();
194         doReturn(true).when(mResponseCallback).isRequestSuccess();
195         PublishProcessor publishProcessor = getPublishProcessor();
196 
197         publishProcessor.onCommandError(mResponseCallback);
198 
199         verify(mDeviceCapabilities).setPresencePublishResult(true);
200         verify(mPublishCtrlCallback).updatePublishRequestResult(anyInt(), any(), any(), eq(null));
201         verify(mResponseCallback).onDestroy();
202         verify(mProcessorState).setPublishingFlag(false);
203         verify(mPublishCtrlCallback).clearRequestCanceledTimer();
204     }
205 
206     @Test
207     @SmallTest
testNetworkResponseWithRetry()208     public void testNetworkResponseWithRetry() throws Exception {
209         doReturn(true).when(mProcessorState).isPublishingNow();
210         doReturn(mTaskId).when(mProcessorState).getCurrentTaskId();
211         doReturn(mTaskId).when(mResponseCallback).getTaskId();
212         doReturn(true).when(mResponseCallback).needRetry();
213         PublishProcessor publishProcessor = getPublishProcessor();
214 
215         publishProcessor.onNetworkResponse(mResponseCallback);
216 
217         verify(mDeviceCapabilities).setPresencePublishResult(false);
218         verify(mProcessorState).increaseRetryCount();
219         verify(mPublishCtrlCallback).requestPublishFromInternal(
220                 eq(PublishController.PUBLISH_TRIGGER_RETRY));
221         verify(mResponseCallback).onDestroy();
222         verify(mProcessorState).setPublishingFlag(false);
223         verify(mPublishCtrlCallback).clearRequestCanceledTimer();
224     }
225 
226     @Test
227     @SmallTest
testNetworkResponseSuccessful()228     public void testNetworkResponseSuccessful() throws Exception {
229         doReturn(true).when(mProcessorState).isPublishingNow();
230         doReturn(mTaskId).when(mProcessorState).getCurrentTaskId();
231         doReturn(mTaskId).when(mResponseCallback).getTaskId();
232         doReturn(false).when(mResponseCallback).needRetry();
233         doReturn(true).when(mResponseCallback).isRequestSuccess();
234         doReturn(Optional.of(200)).when(mResponseCallback).getNetworkRespSipCode();
235 
236         SipDetails details = new SipDetails.Builder(SipDetails.METHOD_PUBLISH)
237                 .setCSeq(10).setSipResponseCode(200, "OK").setCallId("CallId").build();
238         Optional<SipDetails> sipDetails = Optional.ofNullable(details);
239         doReturn(sipDetails).when(mResponseCallback).getSipDetails();
240 
241         PublishProcessor publishProcessor = getPublishProcessor();
242 
243         publishProcessor.onNetworkResponse(mResponseCallback);
244         SipDetails actualInfo = sipDetails.orElse(null);
245 
246         verify(mDeviceCapabilities).setPresencePublishResult(true);
247         verify(mPublishCtrlCallback).updatePublishRequestResult(anyInt(), any(), any(),
248                 eq(actualInfo));
249         verify(mResponseCallback).onDestroy();
250         verify(mProcessorState).setPublishingFlag(false);
251         verify(mPublishCtrlCallback).clearRequestCanceledTimer();
252 
253         verify(mUceStatsWriter).setUceEvent(eq(mSub), eq(UceStatsWriter.PUBLISH_EVENT), eq(true),
254                 eq(0), eq(200));
255     }
256 
257     @Test
258     @SmallTest
testCancelPublishRequest()259     public void testCancelPublishRequest() throws Exception {
260         PublishProcessor publishProcessor = getPublishProcessor();
261 
262         publishProcessor.cancelPublishRequest(mTaskId);
263 
264         verify(mProcessorState).setPublishingFlag(false);
265         verify(mPublishCtrlCallback).clearRequestCanceledTimer();
266     }
267 
268     @Test
269     @SmallTest
testPublishUpdated()270     public void testPublishUpdated() throws Exception {
271         Instant responseTime = Instant.now();
272         doReturn(responseTime).when(mResponseCallback).getResponseTimestamp();
273         doReturn(true).when(mResponseCallback).isRequestSuccess();
274 
275         doReturn(0).when(mResponseCallback).getPublishState();
276         doReturn("").when(mResponseCallback).getPidfXml();
277 
278         SipDetails details = new SipDetails.Builder(SipDetails.METHOD_PUBLISH)
279                 .setCSeq(10).setSipResponseCode(200, "").setCallId("CallId").build();
280         Optional<SipDetails> sipDetails = Optional.ofNullable(details);
281         doReturn(sipDetails).when(mResponseCallback).getSipDetails();
282 
283         PublishProcessor publishProcessor = getPublishProcessor();
284 
285         publishProcessor.publishUpdated(mResponseCallback);
286         SipDetails actualInfo = sipDetails.orElse(null);
287 
288         verify(mDeviceCapabilities).setPresencePublishResult(true);
289         verify(mProcessorState).setLastPublishedTime(any());
290         verify(mProcessorState).resetRetryCount();
291         verify(mPublishCtrlCallback).updatePublishRequestResult(anyInt(), any(), any(),
292                 eq(actualInfo));
293     }
294 
getPublishProcessor()295     private PublishProcessor getPublishProcessor() {
296         PublishProcessor publishProcessor = new TestPublishProcessor(mContext, mSub,
297                 mDeviceCapabilities, mPublishCtrlCallback, mUceStatsWriter);
298         publishProcessor.setProcessorState(mProcessorState);
299         publishProcessor.onRcsConnected(mRcsFeatureManager);
300         return publishProcessor;
301     }
302 
getRcsContactUceCapability()303     private RcsContactUceCapability getRcsContactUceCapability() {
304         Uri contact = Uri.fromParts("sip", "test", null);
305 
306         RcsContactUceCapability.PresenceBuilder builder =
307                 new RcsContactUceCapability.PresenceBuilder(contact,
308                         RcsContactUceCapability.SOURCE_TYPE_CACHED,
309                         RcsContactUceCapability.REQUEST_RESULT_FOUND);
310 
311         RcsContactPresenceTuple.Builder tupleBuilder = new RcsContactPresenceTuple.Builder(
312                 TUPLE_BASIC_STATUS_OPEN, RcsContactPresenceTuple.SERVICE_ID_MMTEL, "1.0");
313 
314         builder.addCapabilityTuple(tupleBuilder.build());
315         return builder.build();
316     }
317 }
318