1 /*
2  * Copyright (C) 2016 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.server.telecom.tests;
18 
19 import static android.provider.CallLog.Calls.MISSED_REASON_NOT_MISSED;
20 import static android.provider.CallLog.Calls.USER_MISSED_CALL_FILTERS_TIMEOUT;
21 import static android.provider.CallLog.Calls.USER_MISSED_NO_VIBRATE;
22 
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertFalse;
25 import static org.junit.Assert.assertNotNull;
26 import static org.junit.Assert.assertNull;
27 import static org.junit.Assert.assertTrue;
28 import static org.mockito.ArgumentMatchers.any;
29 import static org.mockito.ArgumentMatchers.anyInt;
30 import static org.mockito.Mockito.doAnswer;
31 import static org.mockito.Mockito.mock;
32 import static org.mockito.Mockito.when;
33 
34 import android.content.ContentResolver;
35 import android.content.Context;
36 import android.os.Build;
37 import android.telecom.CallAudioState;
38 import android.telecom.Connection;
39 import android.telecom.DisconnectCause;
40 import android.telecom.InCallService;
41 import android.telecom.Log;
42 import android.telecom.Logging.EventManager;
43 import android.telecom.ParcelableCallAnalytics;
44 import android.telecom.TelecomAnalytics;
45 import android.telecom.TelecomManager;
46 import android.telecom.VideoCallImpl;
47 import android.telecom.VideoProfile;
48 import android.telephony.SubscriptionInfo;
49 import android.telephony.SubscriptionManager;
50 import android.util.Base64;
51 
52 import androidx.test.filters.FlakyTest;
53 import androidx.test.filters.MediumTest;
54 import androidx.test.filters.SmallTest;
55 
56 import com.android.internal.util.IndentingPrintWriter;
57 import com.android.server.telecom.Analytics;
58 import com.android.server.telecom.CallAudioRouteStateMachine;
59 import com.android.server.telecom.LogUtils;
60 import com.android.server.telecom.nano.TelecomLogClass;
61 
62 import org.junit.After;
63 import org.junit.Before;
64 import org.junit.Test;
65 import org.junit.runner.RunWith;
66 import org.junit.runners.JUnit4;
67 
68 import java.io.PrintWriter;
69 import java.io.StringWriter;
70 import java.util.Arrays;
71 import java.util.Collections;
72 import java.util.HashSet;
73 import java.util.LinkedList;
74 import java.util.List;
75 import java.util.Map;
76 import java.util.Set;
77 import java.util.concurrent.CountDownLatch;
78 import java.util.concurrent.TimeUnit;
79 
80 @RunWith(JUnit4.class)
81 public class AnalyticsTests extends TelecomSystemTest {
82     private SubscriptionManager mSubscriptionManager;
83 
84     @Override
85     @Before
setUp()86     public void setUp() throws Exception {
87         super.setUp();
88         // this is a mock
89         mSubscriptionManager = mContext.getSystemService(SubscriptionManager.class);
90         when(mSubscriptionManager.createForAllUserProfiles()).thenReturn(mSubscriptionManager);
91         when(mSubscriptionManager.getActiveSubscriptionInfoList())
92                 .thenReturn(Collections.emptyList());
93     }
94 
95     @Override
96     @After
tearDown()97     public void tearDown() throws Exception {
98         super.tearDown();
99     }
100 
101     @MediumTest
102     @Test
testAnalyticsSingleCall()103     public void testAnalyticsSingleCall() throws Exception {
104         IdPair testCall = startAndMakeActiveIncomingCall(
105                 "650-555-1212",
106                 mPhoneAccountA0.getAccountHandle(),
107                 mConnectionServiceFixtureA);
108 
109         Map<String, Analytics.CallInfoImpl> analyticsMap = Analytics.cloneData();
110 
111         assertTrue(analyticsMap.containsKey(testCall.mCallId));
112 
113         Analytics.CallInfoImpl callAnalytics = analyticsMap.get(testCall.mCallId);
114         assertTrue(callAnalytics.startTime > 0);
115         assertEquals(0, callAnalytics.endTime);
116         assertEquals(Analytics.INCOMING_DIRECTION, callAnalytics.callDirection);
117         assertFalse(callAnalytics.isInterrupted);
118         assertNull(callAnalytics.callTerminationReason);
119         assertEquals(mConnectionServiceComponentNameA.flattenToShortString(),
120                 callAnalytics.connectionService);
121 
122         mConnectionServiceFixtureA.
123                 sendSetDisconnected(testCall.mConnectionId, DisconnectCause.ERROR);
124 
125         analyticsMap = Analytics.cloneData();
126         callAnalytics = analyticsMap.get(testCall.mCallId);
127         assertTrue(callAnalytics.endTime > 0);
128         assertNotNull(callAnalytics.callTerminationReason);
129         assertEquals(DisconnectCause.ERROR, callAnalytics.callTerminationReason.getCode());
130 
131         StringWriter sr = new StringWriter();
132         IndentingPrintWriter ip = new IndentingPrintWriter(sr, "    ");
133         Analytics.dump(ip);
134         String dumpResult = sr.toString();
135         String[] expectedFields = {"startTime", "endTime", "direction", "isAdditionalCall",
136                 "isInterrupted", "callTechnologies", "callTerminationReason", "connectionService",
137                 "missedReason"};
138         for (String field : expectedFields) {
139             assertTrue(dumpResult.contains(field));
140         }
141     }
142 
143     @FlakyTest
144     @MediumTest
145     @Test
testAnalyticsDumping()146     public void testAnalyticsDumping() throws Exception {
147         Analytics.reset();
148         IdPair testCall = startAndMakeActiveIncomingCall(
149                 "650-555-1212",
150                 mPhoneAccountA0.getAccountHandle(),
151                 mConnectionServiceFixtureA);
152 
153         mConnectionServiceFixtureA.
154                 sendSetDisconnected(testCall.mConnectionId, DisconnectCause.ERROR);
155         Analytics.CallInfoImpl expectedAnalytics = Analytics.cloneData().get(testCall.mCallId);
156 
157         TelecomManager tm = (TelecomManager) mSpyContext.getSystemService(Context.TELECOM_SERVICE);
158         List<ParcelableCallAnalytics> analyticsList = tm.dumpAnalytics().getCallAnalytics();
159 
160         assertEquals(1, analyticsList.size());
161         ParcelableCallAnalytics pCA = analyticsList.get(0);
162 
163         assertTrue(Math.abs(expectedAnalytics.startTime - pCA.getStartTimeMillis()) <
164                 ParcelableCallAnalytics.MILLIS_IN_5_MINUTES);
165         assertEquals(0, pCA.getStartTimeMillis() % ParcelableCallAnalytics.MILLIS_IN_5_MINUTES);
166         assertTrue(Math.abs((expectedAnalytics.endTime - expectedAnalytics.startTime) -
167                 pCA.getCallDurationMillis()) < ParcelableCallAnalytics.MILLIS_IN_1_SECOND);
168         assertEquals(0, pCA.getCallDurationMillis() % ParcelableCallAnalytics.MILLIS_IN_1_SECOND);
169 
170         assertEquals(expectedAnalytics.callDirection, pCA.getCallType());
171         assertEquals(expectedAnalytics.isAdditionalCall, pCA.isAdditionalCall());
172         assertEquals(expectedAnalytics.isInterrupted, pCA.isInterrupted());
173         assertEquals(expectedAnalytics.callTechnologies, pCA.getCallTechnologies());
174         assertEquals(expectedAnalytics.callTerminationReason.getCode(),
175                 pCA.getCallTerminationCode());
176         assertEquals(expectedAnalytics.connectionService, pCA.getConnectionService());
177         List<ParcelableCallAnalytics.AnalyticsEvent> analyticsEvents = pCA.analyticsEvents();
178         Set<Integer> capturedEvents = new HashSet<>();
179         for (ParcelableCallAnalytics.AnalyticsEvent e : analyticsEvents) {
180             capturedEvents.add(e.getEventName());
181             assertIsRoundedToOneSigFig(e.getTimeSinceLastEvent());
182         }
183         assertTrue(capturedEvents.contains(ParcelableCallAnalytics.AnalyticsEvent.SET_ACTIVE));
184         assertTrue(capturedEvents.contains(
185                 ParcelableCallAnalytics.AnalyticsEvent.FILTERING_INITIATED));
186     }
187 
188     @MediumTest
189     @Test
190     public void testAnalyticsTwoCalls() throws Exception {
191         when(mTimeoutsAdapter.getCallScreeningTimeoutMillis(any(ContentResolver.class)))
192                 .thenReturn((long) TEST_TIMEOUT);
193         IdPair testCall1 = startAndMakeActiveIncomingCall(
194                 "650-555-1212",
195                 mPhoneAccountA0.getAccountHandle(),
196                 mConnectionServiceFixtureA);
197         IdPair testCall2 = startAndMakeActiveOutgoingCall(
198                 "650-555-1213",
199                 mPhoneAccountA0.getAccountHandle(),
200                 mConnectionServiceFixtureA);
201 
202         Map<String, Analytics.CallInfoImpl> analyticsMap = Analytics.cloneData();
203         assertTrue(analyticsMap.containsKey(testCall1.mCallId));
204         assertTrue(analyticsMap.containsKey(testCall2.mCallId));
205 
206         Analytics.CallInfoImpl callAnalytics1 = analyticsMap.get(testCall1.mCallId);
207         Analytics.CallInfoImpl callAnalytics2 = analyticsMap.get(testCall2.mCallId);
208         assertTrue(callAnalytics1.startTime > 0);
209         assertTrue(callAnalytics2.startTime > 0);
210         assertEquals(0, callAnalytics1.endTime);
211         assertEquals(0, callAnalytics2.endTime);
212         long missedReason1 = callAnalytics1.missedReason;
213         assertTrue(missedReason1 == MISSED_REASON_NOT_MISSED
214                 || ((missedReason1 & USER_MISSED_CALL_FILTERS_TIMEOUT) > 0)
215                 || ((missedReason1 & USER_MISSED_NO_VIBRATE) > 0));
216         assertEquals(MISSED_REASON_NOT_MISSED, callAnalytics2.missedReason);
217 
218         assertEquals(Analytics.INCOMING_DIRECTION, callAnalytics1.callDirection);
219         assertEquals(Analytics.OUTGOING_DIRECTION, callAnalytics2.callDirection);
220 
221         assertTrue(callAnalytics1.isInterrupted);
222         assertTrue(callAnalytics2.isAdditionalCall);
223 
224         assertNull(callAnalytics1.callTerminationReason);
225         assertNull(callAnalytics2.callTerminationReason);
226 
227         assertEquals(mConnectionServiceComponentNameA.flattenToShortString(),
228                 callAnalytics1.connectionService);
229         assertEquals(mConnectionServiceComponentNameA.flattenToShortString(),
230                 callAnalytics1.connectionService);
231 
232         mConnectionServiceFixtureA.
233                 sendSetDisconnected(testCall2.mConnectionId, DisconnectCause.REMOTE);
234         mConnectionServiceFixtureA.
235                 sendSetDisconnected(testCall1.mConnectionId, DisconnectCause.ERROR);
236 
237         analyticsMap = Analytics.cloneData();
238         callAnalytics1 = analyticsMap.get(testCall1.mCallId);
239         callAnalytics2 = analyticsMap.get(testCall2.mCallId);
240         assertTrue(callAnalytics1.endTime > 0);
241         assertTrue(callAnalytics2.endTime > 0);
242         assertNotNull(callAnalytics1.callTerminationReason);
243         assertNotNull(callAnalytics2.callTerminationReason);
244         assertEquals(DisconnectCause.ERROR, callAnalytics1.callTerminationReason.getCode());
245         assertEquals(DisconnectCause.REMOTE, callAnalytics2.callTerminationReason.getCode());
246     }
247 
248     @MediumTest
249     @Test
testAnalyticsVideo()250     public void testAnalyticsVideo() throws Exception {
251         Analytics.reset();
252         IdPair callIds = startAndMakeActiveOutgoingCall(
253                 "650-555-1212",
254                 mPhoneAccountA0.getAccountHandle(),
255                 mConnectionServiceFixtureA);
256 
257         CountDownLatch counter = new CountDownLatch(1);
258         InCallService.VideoCall.Callback callback = mock(InCallService.VideoCall.Callback.class);
259 
260         doAnswer(invocation -> {
261             counter.countDown();
262             return null;
263         }).when(callback)
264                 .onSessionModifyResponseReceived(anyInt(), any(VideoProfile.class),
265                         any(VideoProfile.class));
266 
267         mConnectionServiceFixtureA.sendSetVideoProvider(
268                 mConnectionServiceFixtureA.mLatestConnectionId);
269         InCallService.VideoCall videoCall =
270                 mInCallServiceFixtureX.getCall(callIds.mCallId).getVideoCallImpl(
271                         mInCallServiceComponentNameX.getPackageName(), Build.VERSION.SDK_INT);
272         videoCall.registerCallback(callback);
273         ((VideoCallImpl) videoCall).setVideoState(VideoProfile.STATE_BIDIRECTIONAL);
274 
275         videoCall.sendSessionModifyRequest(new VideoProfile(VideoProfile.STATE_RX_ENABLED));
276         counter.await(10000, TimeUnit.MILLISECONDS);
277 
278         StringWriter sw = new StringWriter();
279         PrintWriter pw = new PrintWriter(sw);
280         Analytics.dumpToEncodedProto(mContext, pw, new String[]{});
281         TelecomLogClass.TelecomLog analyticsProto =
282                 TelecomLogClass.TelecomLog.parseFrom(Base64.decode(sw.toString(), Base64.DEFAULT));
283 
284         assertEquals(1, analyticsProto.callLogs.length);
285         TelecomLogClass.VideoEvent[] videoEvents = analyticsProto.callLogs[0].videoEvents;
286         assertEquals(2, videoEvents.length);
287 
288         assertEquals(Analytics.SEND_LOCAL_SESSION_MODIFY_REQUEST, videoEvents[0].getEventName());
289         assertEquals(VideoProfile.STATE_RX_ENABLED, videoEvents[0].getVideoState());
290         assertEquals(-1, videoEvents[0].getTimeSinceLastEventMillis());
291 
292         assertEquals(Analytics.RECEIVE_REMOTE_SESSION_MODIFY_RESPONSE,
293                 videoEvents[1].getEventName());
294         assertEquals(VideoProfile.STATE_RX_ENABLED, videoEvents[1].getVideoState());
295         assertIsRoundedToOneSigFig(videoEvents[1].getTimeSinceLastEventMillis());
296     }
297 
298     @SmallTest
299     @Test
testAnalyticsRounding()300     public void testAnalyticsRounding() {
301         long[] testVals = {0, -1, -10, -100, -57836, 1, 10, 100, 1000, 458457};
302         long[] expected = {0, -1, -10, -100, -60000, 1, 10, 100, 1000, 500000};
303         for (int i = 0; i < testVals.length; i++) {
304             assertEquals(expected[i], Analytics.roundToOneSigFig(testVals[i]));
305         }
306     }
307 
308     @SmallTest
309     @Test
testAnalyticsLogSessionTiming()310     public void testAnalyticsLogSessionTiming() throws Exception {
311         long minTime = 50;
312         Log.startSession(LogUtils.Sessions.CSW_ADD_CONFERENCE_CALL);
313         Thread.sleep(minTime);
314         Log.endSession();
315         TelecomManager tm = (TelecomManager) mSpyContext.getSystemService(Context.TELECOM_SERVICE);
316         List<TelecomAnalytics.SessionTiming> sessions = tm.dumpAnalytics().getSessionTimings();
317         sessions.stream()
318                 .filter(s -> LogUtils.Sessions.CSW_ADD_CONFERENCE_CALL.equals(
319                         Analytics.sSessionIdToLogSession.get(s.getKey())))
320                 .forEach(s -> assertTrue(s.getTime() >= minTime));
321     }
322 
323     @MediumTest
324     @Test
testAnalyticsDumpToProto()325     public void testAnalyticsDumpToProto() throws Exception {
326         Analytics.reset();
327         setupCarrierIds();
328         IdPair testCall = startAndMakeActiveIncomingCall(
329                 "650-555-1212",
330                 mPhoneAccountA0.getAccountHandle(),
331                 mConnectionServiceFixtureA);
332 
333         mConnectionServiceFixtureA.
334                 sendSetDisconnected(testCall.mConnectionId, DisconnectCause.ERROR);
335         Analytics.CallInfoImpl expectedAnalytics = Analytics.cloneData().get(testCall.mCallId);
336 
337         StringWriter sw = new StringWriter();
338         PrintWriter pw = new PrintWriter(sw);
339         Analytics.dumpToEncodedProto(mContext, pw, new String[]{});
340         TelecomLogClass.TelecomLog analyticsProto =
341                 TelecomLogClass.TelecomLog.parseFrom(Base64.decode(sw.toString(), Base64.DEFAULT));
342 
343         assertEquals(1, analyticsProto.getCarrierId());
344         assertEquals(1, analyticsProto.callLogs.length);
345         TelecomLogClass.CallLog callLog = analyticsProto.callLogs[0];
346 
347         assertTrue(Math.abs(expectedAnalytics.startTime - callLog.getStartTime5Min()) <
348                 ParcelableCallAnalytics.MILLIS_IN_5_MINUTES);
349         assertEquals(0, callLog.getStartTime5Min() % ParcelableCallAnalytics.MILLIS_IN_5_MINUTES);
350         assertTrue(Math.abs((expectedAnalytics.endTime - expectedAnalytics.startTime) -
351                 callLog.getCallDurationMillis()) < ParcelableCallAnalytics.MILLIS_IN_1_SECOND);
352         assertEquals(0,
353                 callLog.getCallDurationMillis() % ParcelableCallAnalytics.MILLIS_IN_1_SECOND);
354 
355         assertEquals(expectedAnalytics.callDirection, callLog.getType());
356         assertEquals(expectedAnalytics.isAdditionalCall, callLog.getIsAdditionalCall());
357         assertEquals(expectedAnalytics.isInterrupted, callLog.getIsInterrupted());
358         assertEquals(expectedAnalytics.callTechnologies, callLog.getCallTechnologies());
359         assertEquals(expectedAnalytics.callTerminationReason.getCode(),
360                 callLog.getCallTerminationCode());
361         assertEquals(expectedAnalytics.connectionService, callLog.connectionService[0]);
362         TelecomLogClass.Event[] analyticsEvents = callLog.callEvents;
363         Set<Integer> capturedEvents = new HashSet<>();
364         for (TelecomLogClass.Event e : analyticsEvents) {
365             capturedEvents.add(e.getEventName());
366             assertIsRoundedToOneSigFig(e.getTimeSinceLastEventMillis());
367         }
368         assertTrue(capturedEvents.contains(ParcelableCallAnalytics.AnalyticsEvent.SET_ACTIVE));
369         assertTrue(capturedEvents.contains(
370                 ParcelableCallAnalytics.AnalyticsEvent.FILTERING_INITIATED));
371     }
372 
373     @MediumTest
374     @Test
375     public void testAnalyticsAudioRoutes() throws Exception {
376         Analytics.reset();
377         IdPair testCall = startAndMakeActiveIncomingCall(
378                 "650-555-1212",
379                 mPhoneAccountA0.getAccountHandle(),
380                 mConnectionServiceFixtureA);
381         List<Integer> audioRoutes = new LinkedList<>();
382 
383         waitForHandlerAction(
384                 mTelecomSystem.getCallsManager().getCallAudioManager()
385                         .getCallAudioRouteAdapter().getAdapterHandler(),
386                 TEST_TIMEOUT);
387         waitForHandlerAction(
388                 mTelecomSystem.getCallsManager().getCallAudioManager()
389                         .getCallAudioModeStateMachine().getHandler(),
390                 TEST_TIMEOUT);
391         audioRoutes.add(mInCallServiceFixtureX.mCallAudioState.getRoute());
392         mInCallServiceFixtureX.getInCallAdapter().setAudioRoute(CallAudioState.ROUTE_SPEAKER, null);
393         waitForHandlerAction(
394                 mTelecomSystem.getCallsManager().getCallAudioManager()
395                         .getCallAudioRouteAdapter().getAdapterHandler(),
396                 TEST_TIMEOUT);
397         waitForHandlerAction(
398                 mTelecomSystem.getCallsManager().getCallAudioManager()
399                         .getCallAudioModeStateMachine().getHandler(),
400                 TEST_TIMEOUT);
401         audioRoutes.add(CallAudioState.ROUTE_SPEAKER);
402 
403         Map<String, Analytics.CallInfoImpl> analyticsMap = Analytics.cloneData();
404         assertTrue(analyticsMap.containsKey(testCall.mCallId));
405 
406         Analytics.CallInfoImpl callAnalytics = analyticsMap.get(testCall.mCallId);
407         List<EventManager.Event> events = callAnalytics.callEvents.getEvents();
408         for (int route : audioRoutes) {
409             String logEvent = CallAudioRouteStateMachine.AUDIO_ROUTE_TO_LOG_EVENT.get(route);
410             assertTrue(events.stream().anyMatch(event -> event.eventId.equals(logEvent)));
411         }
412     }
413 
414     @MediumTest
415     @Test
416     public void testAnalyticsConnectionProperties() throws Exception {
417         Analytics.reset();
418         IdPair testCall = startAndMakeActiveIncomingCall(
419                 "650-555-1212",
420                 mPhoneAccountA0.getAccountHandle(),
421                 mConnectionServiceFixtureA);
422 
423         int properties1 = Connection.PROPERTY_IS_DOWNGRADED_CONFERENCE
424                 | Connection.PROPERTY_WIFI
425                 | Connection.PROPERTY_EMERGENCY_CALLBACK_MODE;
426         int properties2 = Connection.PROPERTY_HIGH_DEF_AUDIO
427                 | Connection.PROPERTY_WIFI;
428         int expectedProperties = properties1 | properties2;
429 
430         mConnectionServiceFixtureA.mConnectionById.get(testCall.mConnectionId).properties =
431                 properties1;
432         mConnectionServiceFixtureA.sendSetConnectionProperties(testCall.mConnectionId);
433         mConnectionServiceFixtureA.mConnectionById.get(testCall.mConnectionId).properties =
434                 properties2;
435         mConnectionServiceFixtureA.sendSetConnectionProperties(testCall.mConnectionId);
436 
437         mConnectionServiceFixtureA.
438                 sendSetDisconnected(testCall.mConnectionId, DisconnectCause.ERROR);
439 
440         StringWriter sw = new StringWriter();
441         PrintWriter pw = new PrintWriter(sw);
442         Analytics.dumpToEncodedProto(mContext, pw, new String[]{});
443         TelecomLogClass.TelecomLog analyticsProto =
444                 TelecomLogClass.TelecomLog.parseFrom(Base64.decode(sw.toString(), Base64.DEFAULT));
445 
446         assertEquals(expectedProperties,
447                 analyticsProto.callLogs[0].getConnectionProperties() & expectedProperties);
448     }
449 
450     @SmallTest
451     @Test
452     public void testAnalyticsMaxSize() throws Exception {
453         Analytics.reset();
454         for (int i = 0; i < Analytics.MAX_NUM_CALLS_TO_STORE * 2; i++) {
455             Analytics.initiateCallAnalytics(String.valueOf(i), Analytics.INCOMING_DIRECTION)
456                     .addCallTechnology(i);
457         }
458 
459         StringWriter sw = new StringWriter();
460         PrintWriter pw = new PrintWriter(sw);
461         Analytics.dumpToEncodedProto(mContext, pw, new String[]{});
462         TelecomLogClass.TelecomLog analyticsProto =
463                 TelecomLogClass.TelecomLog.parseFrom(Base64.decode(sw.toString(), Base64.DEFAULT));
464 
465         assertEquals(Analytics.MAX_NUM_CALLS_TO_STORE, analyticsProto.callLogs.length);
466         assertEquals(Arrays.stream(analyticsProto.callLogs)
467                 .filter(x -> x.getCallTechnologies() < 100)
468                 .count(), 0);
469     }
470 
471     private void assertIsRoundedToOneSigFig(long x) {
472         assertEquals(x, Analytics.roundToOneSigFig(x));
473     }
474 
475     private void setupCarrierIds() {
476         SubscriptionInfo subInfo1 = mock(SubscriptionInfo.class);
477         SubscriptionInfo subInfo2 = mock(SubscriptionInfo.class);
478         when(subInfo1.getCarrierId()).thenReturn(1);
479         when(subInfo2.getCarrierId()).thenReturn(2);
480         when(subInfo1.isOpportunistic()).thenReturn(false);
481         when(subInfo2.isOpportunistic()).thenReturn(true);
482         when(subInfo1.getSimSlotIndex()).thenReturn(0);
483         when(subInfo2.getSimSlotIndex()).thenReturn(1);
484         when(mSubscriptionManager.getActiveSubscriptionInfoList())
485                 .thenReturn(Arrays.asList(subInfo2, subInfo1));
486     }
487 }
488