1 /*
2  * Copyright (C) 2023 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.internal.telephony.satellite;
18 
19 import static android.telephony.ServiceState.STATE_OUT_OF_SERVICE;
20 import static android.telephony.TelephonyManager.EXTRA_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE;
21 import static android.telephony.TelephonyManager.EXTRA_EMERGENCY_CALL_TO_SATELLITE_LAUNCH_INTENT;
22 import static android.telephony.satellite.SatelliteManager.EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS;
23 import static android.telephony.satellite.SatelliteManager.EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911;
24 
25 import static org.junit.Assert.assertEquals;
26 import static org.junit.Assert.assertFalse;
27 import static org.junit.Assert.assertNotNull;
28 import static org.junit.Assert.assertNull;
29 import static org.junit.Assert.assertTrue;
30 import static org.mockito.ArgumentMatchers.any;
31 import static org.mockito.ArgumentMatchers.anyInt;
32 import static org.mockito.Mockito.times;
33 import static org.mockito.Mockito.verify;
34 import static org.mockito.Mockito.when;
35 
36 import android.annotation.NonNull;
37 import android.app.PendingIntent;
38 import android.content.ComponentName;
39 import android.content.Context;
40 import android.content.Intent;
41 import android.content.res.Resources;
42 import android.net.Uri;
43 import android.os.Bundle;
44 import android.os.Looper;
45 import android.os.OutcomeReceiver;
46 import android.os.RemoteException;
47 import android.telecom.Connection;
48 import android.telecom.TelecomManager;
49 import android.telephony.BinderCacheManager;
50 import android.telephony.ServiceState;
51 import android.telephony.SubscriptionManager;
52 import android.telephony.TelephonyManager;
53 import android.telephony.ims.RegistrationManager;
54 import android.telephony.satellite.ISatelliteProvisionStateCallback;
55 import android.telephony.satellite.SatelliteManager;
56 import android.testing.AndroidTestingRunner;
57 import android.testing.TestableLooper;
58 import android.text.TextUtils;
59 import android.util.Log;
60 
61 import com.android.ims.ImsException;
62 import com.android.ims.ImsManager;
63 import com.android.internal.R;
64 import com.android.internal.telephony.Phone;
65 import com.android.internal.telephony.PhoneFactory;
66 import com.android.internal.telephony.TelephonyTest;
67 import com.android.internal.telephony.flags.FeatureFlags;
68 
69 import org.junit.After;
70 import org.junit.Before;
71 import org.junit.Test;
72 import org.junit.runner.RunWith;
73 import org.mockito.Mock;
74 import org.mockito.Mockito;
75 import org.mockito.MockitoAnnotations;
76 
77 import java.util.ArrayList;
78 import java.util.HashMap;
79 import java.util.HashSet;
80 import java.util.List;
81 import java.util.Map;
82 import java.util.Set;
83 import java.util.concurrent.Executor;
84 
85 /**
86  * Unit tests for SatelliteSOSMessageRecommender
87  */
88 @RunWith(AndroidTestingRunner.class)
89 @TestableLooper.RunWithLooper
90 public class SatelliteSOSMessageRecommenderTest extends TelephonyTest {
91     private static final String TAG = "SatelliteSOSMessageRecommenderTest";
92     private static final int TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS = 500;
93     private static final int PHONE_ID = 0;
94     private static final int PHONE_ID2 = 1;
95     private static final String CALL_ID = "CALL_ID";
96     private static final String WRONG_CALL_ID = "WRONG_CALL_ID";
97     private static final String DEFAULT_SATELLITE_MESSAGING_PACKAGE = "android.com.google.default";
98     private static final String DEFAULT_SATELLITE_MESSAGING_CLASS =
99             "android.com.google.default.SmsMmsApp";
100     private static final String DEFAULT_HANDOVER_INTENT_ACTION =
101             "android.com.vendor.action.EMERGENCY_MESSAGING";
102     private static final String DEFAULT_T911_HANDOVER_INTENT_ACTION = Intent.ACTION_SENDTO;
103     private TestSatelliteController mTestSatelliteController;
104     private TestImsManager mTestImsManager;
105     @Mock
106     private Resources mResources;
107     @Mock
108     private ImsManager.MmTelFeatureConnectionFactory mMmTelFeatureConnectionFactory;
109     @Mock
110     private FeatureFlags mFeatureFlags;
111     private TestConnection mTestConnection;
112     private Uri mTestConnectionAddress = Uri.parse("tel:1234");
113     private TestSOSMessageRecommender mTestSOSMessageRecommender;
114     private ServiceState mServiceState2;
115 
116     @Before
setUp()117     public void setUp() throws Exception {
118         super.setUp(getClass().getSimpleName());
119         MockitoAnnotations.initMocks(this);
120 
121         when(mContext.getResources()).thenReturn(mResources);
122         when(mResources.getString(R.string.config_satellite_service_package))
123                 .thenReturn("");
124         when(mResources.getString(R.string.config_satellite_emergency_handover_intent_action))
125                 .thenReturn(DEFAULT_HANDOVER_INTENT_ACTION);
126         when(mResources.getInteger(
127                 R.integer.config_emergency_call_wait_for_connection_timeout_millis))
128                 .thenReturn(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
129         when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true);
130         mTestSatelliteController = new TestSatelliteController(mContext,
131                 Looper.myLooper(), mFeatureFlags);
132         mTestImsManager = new TestImsManager(
133                 mContext, PHONE_ID, mMmTelFeatureConnectionFactory, null, null, null);
134         mTestConnection = new TestConnection(CALL_ID);
135         mTestConnection.setAddress(mTestConnectionAddress, TelecomManager.PRESENTATION_ALLOWED);
136         mPhones = new Phone[] {mPhone, mPhone2};
137         replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
138         mServiceState2 = Mockito.mock(ServiceState.class);
139         when(mPhone.getServiceState()).thenReturn(mServiceState);
140         when(mPhone.getPhoneId()).thenReturn(PHONE_ID);
141         when(mPhone2.getServiceState()).thenReturn(mServiceState2);
142         when(mPhone2.getPhoneId()).thenReturn(PHONE_ID2);
143         mTestSOSMessageRecommender = new TestSOSMessageRecommender(mContext, Looper.myLooper(),
144                 mTestSatelliteController, mTestImsManager);
145         when(mServiceState.getState()).thenReturn(STATE_OUT_OF_SERVICE);
146         when(mServiceState2.getState()).thenReturn(STATE_OUT_OF_SERVICE);
147         when(mPhone.isImsRegistered()).thenReturn(false);
148         when(mPhone2.isImsRegistered()).thenReturn(false);
149     }
150 
151     @After
tearDown()152     public void tearDown() throws Exception {
153         super.tearDown();
154     }
155 
156     @Test
testTimeoutBeforeEmergencyCallEnd_T911()157     public void testTimeoutBeforeEmergencyCallEnd_T911() {
158         testTimeoutBeforeEmergencyCallEnd(EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911,
159                 DEFAULT_SATELLITE_MESSAGING_PACKAGE, DEFAULT_SATELLITE_MESSAGING_CLASS,
160                 DEFAULT_T911_HANDOVER_INTENT_ACTION);
161     }
162 
163     @Test
testTimeoutBeforeEmergencyCallEnd_SOS_WithValidHandoverAppConfigured()164     public void testTimeoutBeforeEmergencyCallEnd_SOS_WithValidHandoverAppConfigured() {
165         String satelliteHandoverApp =
166                 "android.com.vendor.message;android.com.vendor.message.SmsApp";
167         when(mResources.getString(R.string.config_oem_enabled_satellite_sos_handover_app))
168                 .thenReturn(satelliteHandoverApp);
169         mTestSatelliteController.setSatelliteConnectedViaCarrierWithinHysteresisTime(false);
170         testTimeoutBeforeEmergencyCallEnd(EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS,
171                 "android.com.vendor.message", "android.com.vendor.message.SmsApp",
172                 DEFAULT_HANDOVER_INTENT_ACTION);
173     }
174 
175     @Test
testTimeoutBeforeEmergencyCallEnd_SOS_WithInValidHandoverAppConfigured()176     public void testTimeoutBeforeEmergencyCallEnd_SOS_WithInValidHandoverAppConfigured() {
177         String satelliteHandoverApp =
178                 "android.com.vendor.message;android.com.vendor.message.SmsApp;abc";
179         when(mResources.getString(R.string.config_oem_enabled_satellite_sos_handover_app))
180                 .thenReturn(satelliteHandoverApp);
181         mTestSatelliteController.setSatelliteConnectedViaCarrierWithinHysteresisTime(false);
182         testTimeoutBeforeEmergencyCallEnd(EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS, "", "",
183                 DEFAULT_HANDOVER_INTENT_ACTION);
184     }
185 
186     @Test
testTimeoutBeforeEmergencyCallEnd_SOS_WithoutHandoverAppConfigured()187     public void testTimeoutBeforeEmergencyCallEnd_SOS_WithoutHandoverAppConfigured() {
188         when(mResources.getString(R.string.config_oem_enabled_satellite_sos_handover_app))
189                 .thenReturn("");
190         mTestSatelliteController.setSatelliteConnectedViaCarrierWithinHysteresisTime(false);
191         testTimeoutBeforeEmergencyCallEnd(EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS, "", "",
192                 DEFAULT_HANDOVER_INTENT_ACTION);
193     }
194 
195     @Test
testStartTimer_emergencyCallNull()196     public void testStartTimer_emergencyCallNull() {
197         when(mServiceState.getState()).thenReturn(STATE_OUT_OF_SERVICE);
198         when(mServiceState2.getState()).thenReturn(STATE_OUT_OF_SERVICE);
199         mTestSOSMessageRecommender.isSatelliteAllowedCallback = null;
200         mTestSOSMessageRecommender.onEmergencyCallStarted(null);
201         processAllMessages();
202         assertFalse(mTestSOSMessageRecommender.isTimerStarted());
203         assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
204     }
205 
testTimeoutBeforeEmergencyCallEnd(int expectedHandoverType, String expectedPackageName, String expectedClassName, String expectedAction)206     private void testTimeoutBeforeEmergencyCallEnd(int expectedHandoverType,
207             String expectedPackageName, String expectedClassName, String expectedAction) {
208         mTestSOSMessageRecommender.isSatelliteAllowedCallback = null;
209         mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
210         processAllMessages();
211         assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
212         assertRegisterForStateChangedEventsTriggered(mPhone, 1,  1);
213         assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 1);
214         assertNull(mTestSOSMessageRecommender.isSatelliteAllowedCallback);
215 
216         // Move Location service to emergency mode
217         mTestSOSMessageRecommender.onEmergencyCallConnectionStateChanged(
218                 mTestConnection.getTelecomCallId(), Connection.STATE_DIALING);
219         processAllMessages();
220         assertNotNull(mTestSOSMessageRecommender.isSatelliteAllowedCallback);
221 
222         // Wait for the timeout to expires
223         mTestSOSMessageRecommender.isSatelliteAllowedCallback.onResult(true);
224         moveTimeForward(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
225         processAllMessages();
226         if (TextUtils.isEmpty(expectedPackageName) || TextUtils.isEmpty(expectedClassName)) {
227             assertTrue(mTestConnection.isEventWithoutLaunchIntentSent(
228                     TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE, expectedHandoverType));
229         } else {
230             assertTrue(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE,
231                     expectedHandoverType, expectedPackageName, expectedClassName, expectedAction));
232         }
233         assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1);
234         assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 1);
235     }
236 
237     @Test
testTimeoutBeforeEmergencyCallEnd_EventDisplayEmergencyMessageNotSent()238     public void testTimeoutBeforeEmergencyCallEnd_EventDisplayEmergencyMessageNotSent() {
239         mTestSatelliteController.setSatelliteConnectedViaCarrierWithinHysteresisTime(false);
240         mTestSatelliteController.setIsSatelliteViaOemProvisioned(false);
241         mTestSOSMessageRecommender.isSatelliteAllowedCallback = null;
242         mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
243         processAllMessages();
244         assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
245         assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1);
246         assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 1);
247         assertNull(mTestSOSMessageRecommender.isSatelliteAllowedCallback);
248 
249         // Move Location service to emergency mode
250         mTestSOSMessageRecommender.onEmergencyCallConnectionStateChanged(
251                 mTestConnection.getTelecomCallId(), Connection.STATE_DIALING);
252         processAllMessages();
253         assertNotNull(mTestSOSMessageRecommender.isSatelliteAllowedCallback);
254 
255         // Wait for the timeout to expires
256         mTestSOSMessageRecommender.isSatelliteAllowedCallback.onResult(true);
257         moveTimeForward(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
258         processAllMessages();
259         assertFalse(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE));
260         assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1);
261         assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 1);
262     }
263 
264     @Test
testTimeoutBeforeEmergencyCallEnd_T911_FromNotConnectedToConnected()265     public void testTimeoutBeforeEmergencyCallEnd_T911_FromNotConnectedToConnected() {
266         mTestSOSMessageRecommender.isSatelliteAllowedCallback = null;
267         mTestSatelliteController.setSatelliteConnectedViaCarrierWithinHysteresisTime(false);
268         mTestSatelliteController.isOemEnabledSatelliteSupported = false;
269         mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
270         processAllMessages();
271         assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
272         assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1);
273         assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 1);
274         assertNull(mTestSOSMessageRecommender.isSatelliteAllowedCallback);
275 
276         // Move Location service to emergency mode
277         mTestSOSMessageRecommender.onEmergencyCallConnectionStateChanged(
278                 mTestConnection.getTelecomCallId(), Connection.STATE_DIALING);
279         processAllMessages();
280         assertNull(mTestSOSMessageRecommender.isSatelliteAllowedCallback);
281 
282         mTestSatelliteController.setSatelliteConnectedViaCarrierWithinHysteresisTime(true);
283         // Wait for the timeout to expires
284         moveTimeForward(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
285         processAllMessages();
286         assertTrue(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE,
287                 EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911,
288                 DEFAULT_SATELLITE_MESSAGING_PACKAGE, DEFAULT_SATELLITE_MESSAGING_CLASS,
289                 DEFAULT_T911_HANDOVER_INTENT_ACTION));
290         assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1);
291         assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 1);
292         mTestSatelliteController.isOemEnabledSatelliteSupported = true;
293     }
294 
295     @Test
testStopTrackingCallBeforeTimeout_ConnectionActive()296     public void testStopTrackingCallBeforeTimeout_ConnectionActive() {
297         testStopTrackingCallBeforeTimeout(Connection.STATE_ACTIVE);
298     }
299 
300     @Test
testStopTrackingCallBeforeTimeout_ConnectionDisconnected()301     public void testStopTrackingCallBeforeTimeout_ConnectionDisconnected() {
302         testStopTrackingCallBeforeTimeout(Connection.STATE_DISCONNECTED);
303     }
304 
305     @Test
testNetworkStateChangedBeforeTimeout()306     public void testNetworkStateChangedBeforeTimeout() {
307         mTestSOSMessageRecommender.isSatelliteAllowedCallback = null;
308         mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
309         processAllMessages();
310         assertTrue(mTestSOSMessageRecommender.isTimerStarted());
311         assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
312         assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1);
313         assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 1);
314         assertNull(mTestSOSMessageRecommender.isSatelliteAllowedCallback);
315 
316         // Move Location service to emergency mode
317         mTestSOSMessageRecommender.onEmergencyCallConnectionStateChanged(
318                 mTestConnection.getTelecomCallId(), Connection.STATE_DIALING);
319         processAllMessages();
320         assertNotNull(mTestSOSMessageRecommender.isSatelliteAllowedCallback);
321 
322         // Wait for the timeout to expires
323         mTestSOSMessageRecommender.isSatelliteAllowedCallback.onResult(true);
324         moveTimeForward(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
325         processAllMessages();
326 
327         assertTrue(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE,
328                 EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911, DEFAULT_SATELLITE_MESSAGING_PACKAGE,
329                 DEFAULT_SATELLITE_MESSAGING_CLASS, DEFAULT_T911_HANDOVER_INTENT_ACTION));
330         assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1);
331         assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 1);
332         assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
333     }
334 
335     @Test
testSatelliteProvisionStateChangedBeforeTimeout()336     public void testSatelliteProvisionStateChangedBeforeTimeout() {
337         mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
338         processAllMessages();
339 
340         assertTrue(mTestSOSMessageRecommender.isTimerStarted());
341         assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
342         assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1);
343         assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 1);
344 
345         mTestSatelliteController.sendProvisionStateChangedEvent(
346                 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false);
347         processAllMessages();
348 
349         assertFalse(mTestSOSMessageRecommender.isTimerStarted());
350         assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
351         assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1);
352         assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 1);
353 
354         mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
355         processAllMessages();
356         assertTrue(mTestSOSMessageRecommender.isTimerStarted());
357         assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
358         assertRegisterForStateChangedEventsTriggered(mPhone, 2, 2);
359         assertRegisterForStateChangedEventsTriggered(mPhone2, 2, 2);
360 
361         // Move Location service to emergency mode
362         mTestSOSMessageRecommender.isSatelliteAllowedCallback = null;
363         mTestSOSMessageRecommender.onEmergencyCallConnectionStateChanged(
364                 mTestConnection.getTelecomCallId(), Connection.STATE_DIALING);
365         processAllMessages();
366         assertNotNull(mTestSOSMessageRecommender.isSatelliteAllowedCallback);
367 
368         mTestSatelliteController.sendProvisionStateChangedEvent(
369                 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, true);
370 
371         // Wait for the timeout to expires
372         mTestSOSMessageRecommender.isSatelliteAllowedCallback.onResult(true);
373         moveTimeForward(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
374         processAllMessages();
375 
376         assertTrue(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE,
377                 EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911, DEFAULT_SATELLITE_MESSAGING_PACKAGE,
378                 DEFAULT_SATELLITE_MESSAGING_CLASS, DEFAULT_T911_HANDOVER_INTENT_ACTION));
379         assertFalse(mTestSOSMessageRecommender.isTimerStarted());
380         assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
381         assertUnregisterForStateChangedEventsTriggered(mPhone, 2, 2);
382         assertUnregisterForStateChangedEventsTriggered(mPhone2, 2, 2);
383     }
384 
385     @Test
testEmergencyCallRedialBeforeTimeout()386     public void testEmergencyCallRedialBeforeTimeout() {
387         mTestSOSMessageRecommender.isSatelliteAllowedCallback = null;
388         mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
389         processAllMessages();
390         assertTrue(mTestSOSMessageRecommender.isTimerStarted());
391         assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
392         assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1);
393         assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 1);
394         assertNull(mTestSOSMessageRecommender.isSatelliteAllowedCallback);
395 
396         mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
397         processAllMessages();
398         assertNull(mTestSOSMessageRecommender.isSatelliteAllowedCallback);
399         assertTrue(mTestSOSMessageRecommender.isTimerStarted());
400         assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
401         assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1);
402         assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 1);
403 
404         // Move Location service to emergency mode
405         mTestSOSMessageRecommender.onEmergencyCallConnectionStateChanged(
406                 mTestConnection.getTelecomCallId(), Connection.STATE_DIALING);
407         processAllMessages();
408         assertNotNull(mTestSOSMessageRecommender.isSatelliteAllowedCallback);
409 
410         // Wait for the timeout to expires and satellite access restriction checking result
411         mTestSOSMessageRecommender.isSatelliteAllowedCallback.onResult(true);
412         moveTimeForward(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
413         processAllMessages();
414 
415         assertTrue(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE,
416                 EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911, DEFAULT_SATELLITE_MESSAGING_PACKAGE,
417                 DEFAULT_SATELLITE_MESSAGING_CLASS, DEFAULT_T911_HANDOVER_INTENT_ACTION));
418         assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1);
419         assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 1);
420         assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
421         assertFalse(mTestSOSMessageRecommender.isTimerStarted());
422     }
423 
424     @Test
testCellularServiceStateChangedBeforeTimeout_InServiceToOutOfService()425     public void testCellularServiceStateChangedBeforeTimeout_InServiceToOutOfService() {
426         testCellularServiceStateChangedBeforeTimeout(
427                 ServiceState.STATE_IN_SERVICE, STATE_OUT_OF_SERVICE);
428     }
429 
430     @Test
testCellularServiceStateChangedBeforeTimeout_InServiceToPowerOff()431     public void testCellularServiceStateChangedBeforeTimeout_InServiceToPowerOff() {
432         testCellularServiceStateChangedBeforeTimeout(
433                 ServiceState.STATE_IN_SERVICE, ServiceState.STATE_POWER_OFF);
434     }
435 
436     @Test
testCellularServiceStateChangedBeforeTimeout_EmergencyOnlyToOutOfService()437     public void testCellularServiceStateChangedBeforeTimeout_EmergencyOnlyToOutOfService() {
438         testCellularServiceStateChangedBeforeTimeout(
439                 ServiceState.STATE_EMERGENCY_ONLY, STATE_OUT_OF_SERVICE);
440     }
441 
442     @Test
testCellularServiceStateChangedBeforeTimeout_EmergencyOnlyToPowerOff()443     public void testCellularServiceStateChangedBeforeTimeout_EmergencyOnlyToPowerOff() {
444         testCellularServiceStateChangedBeforeTimeout(
445                 ServiceState.STATE_EMERGENCY_ONLY, ServiceState.STATE_POWER_OFF);
446     }
447 
448     @Test
testOnEmergencyCallConnectionStateChangedWithWrongCallId()449     public void testOnEmergencyCallConnectionStateChangedWithWrongCallId() {
450         mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
451         processAllMessages();
452 
453         assertTrue(mTestSOSMessageRecommender.isTimerStarted());
454         assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
455         assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1);
456         assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 1);
457 
458         mTestSOSMessageRecommender.onEmergencyCallConnectionStateChanged(
459                 WRONG_CALL_ID, Connection.STATE_ACTIVE);
460         processAllMessages();
461 
462         assertFalse(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE));
463         assertFalse(mTestSOSMessageRecommender.isTimerStarted());
464         assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
465         assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1);
466         assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 1);
467     }
468 
469     @Test
testSatelliteNotAllowedInCurrentLocation()470     public void testSatelliteNotAllowedInCurrentLocation() {
471         mTestSOSMessageRecommender.isSatelliteAllowedCallback = null;
472         mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
473         processAllMessages();
474         assertNull(mTestSOSMessageRecommender.isSatelliteAllowedCallback);
475         assertTrue(mTestSOSMessageRecommender.isTimerStarted());
476         assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
477 
478         // Move Location service to emergency mode
479         mTestSOSMessageRecommender.onEmergencyCallConnectionStateChanged(
480                 mTestConnection.getTelecomCallId(), Connection.STATE_DIALING);
481         processAllMessages();
482         assertNotNull(mTestSOSMessageRecommender.isSatelliteAllowedCallback);
483 
484         mTestSOSMessageRecommender.isSatelliteAllowedCallback.onResult(false);
485         moveTimeForward(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
486         processAllMessages();
487 
488         assertFalse(mTestSOSMessageRecommender.isTimerStarted());
489         assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
490         assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1);
491         assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 1);
492         assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1);
493         assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 1);
494     }
495 
496     @Test
testOnEmergencyCallStarted()497     public void testOnEmergencyCallStarted() {
498         SatelliteController satelliteController = new SatelliteController(
499                 mContext, Looper.myLooper(), mFeatureFlags);
500         TestSOSMessageRecommender testSOSMessageRecommender = new TestSOSMessageRecommender(
501                 mContext,
502                 Looper.myLooper(),
503                 satelliteController, mTestImsManager);
504         testSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
505         processAllMessages();
506 
507         assertFalse(testSOSMessageRecommender.isTimerStarted());
508         assertEquals(0, testSOSMessageRecommender.getCountOfTimerStarted());
509     }
510 
511     @Test
testIsSatelliteViaOemAvailable()512     public void testIsSatelliteViaOemAvailable() {
513         Boolean originalIsSatelliteViaOemProvisioned =
514                 mTestSatelliteController.mIsSatelliteViaOemProvisioned;
515 
516         mTestSatelliteController.mIsSatelliteViaOemProvisioned = null;
517         assertFalse(mTestSOSMessageRecommender.isSatelliteViaOemAvailable());
518 
519         mTestSatelliteController.mIsSatelliteViaOemProvisioned = true;
520         assertTrue(mTestSOSMessageRecommender.isSatelliteViaOemAvailable());
521 
522         mTestSatelliteController.mIsSatelliteViaOemProvisioned = false;
523         assertFalse(mTestSOSMessageRecommender.isSatelliteViaOemAvailable());
524 
525         mTestSatelliteController.mIsSatelliteViaOemProvisioned =
526                 originalIsSatelliteViaOemProvisioned;
527     }
528 
529     @Test
testSelectEmergencyCallWaitForConnectionTimeoutDuration()530     public void testSelectEmergencyCallWaitForConnectionTimeoutDuration() {
531         // Both OEM and carrier don't support satellite
532         mTestSatelliteController.isSatelliteEmergencyMessagingSupportedViaCarrier = false;
533         mTestSatelliteController.isOemEnabledSatelliteSupported = false;
534         mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
535         processAllMessages();
536         assertEquals(0, mTestSOSMessageRecommender.getTimeOutMillis());
537 
538         // Only OEM support satellite
539         mTestSatelliteController.isOemEnabledSatelliteSupported = true;
540         mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
541         processAllMessages();
542         assertEquals(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS,
543                 mTestSOSMessageRecommender.getTimeOutMillis());
544 
545         // Both OEM and carrier support satellite. Thus, carrier's timeout duration will be used
546         long carrierTimeoutMillis = 1000;
547         mTestSatelliteController.isSatelliteEmergencyMessagingSupportedViaCarrier = true;
548         mTestSatelliteController.carrierEmergencyCallWaitForConnectionTimeoutMillis =
549                 carrierTimeoutMillis;
550         mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
551         processAllMessages();
552         assertEquals(carrierTimeoutMillis, mTestSOSMessageRecommender.getTimeOutMillis());
553     }
554 
testStopTrackingCallBeforeTimeout( @onnection.ConnectionState int connectionState)555     private void testStopTrackingCallBeforeTimeout(
556             @Connection.ConnectionState int connectionState) {
557         mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
558         processAllMessages();
559 
560         assertTrue(mTestSOSMessageRecommender.isTimerStarted());
561         assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
562         assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1);
563         assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 1);
564 
565         mTestSOSMessageRecommender.onEmergencyCallConnectionStateChanged(CALL_ID, connectionState);
566         processAllMessages();
567 
568         assertFalse(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE));
569         assertFalse(mTestSOSMessageRecommender.isTimerStarted());
570         assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
571         assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1);
572         assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 1);
573     }
574 
testCellularServiceStateChangedBeforeTimeout( @erviceState.RegState int availableServiceState, @ServiceState.RegState int unavailableServiceState)575     private void testCellularServiceStateChangedBeforeTimeout(
576             @ServiceState.RegState int availableServiceState,
577             @ServiceState.RegState int unavailableServiceState) {
578         mTestSOSMessageRecommender.isSatelliteAllowedCallback = null;
579         mTestSOSMessageRecommender.onEmergencyCallStarted(mTestConnection);
580         processAllMessages();
581         assertNull(mTestSOSMessageRecommender.isSatelliteAllowedCallback);
582         assertTrue(mTestSOSMessageRecommender.isTimerStarted());
583         assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
584         assertRegisterForStateChangedEventsTriggered(mPhone, 1, 1);
585         assertRegisterForStateChangedEventsTriggered(mPhone2, 1, 1);
586 
587         when(mServiceState.getState()).thenReturn(availableServiceState);
588         mTestSOSMessageRecommender.sendServiceStateChangedEvent();
589         processAllMessages();
590         assertFalse(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE));
591         assertFalse(mTestSOSMessageRecommender.isTimerStarted());
592         assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
593         assertUnregisterForStateChangedEventsTriggered(mPhone, 0, 0);
594         assertUnregisterForStateChangedEventsTriggered(mPhone2, 0, 0);
595 
596         when(mServiceState.getState()).thenReturn(unavailableServiceState);
597         when(mServiceState2.getState()).thenReturn(availableServiceState);
598         mTestSOSMessageRecommender.sendServiceStateChangedEvent();
599         processAllMessages();
600         assertFalse(mTestSOSMessageRecommender.isTimerStarted());
601         assertEquals(1, mTestSOSMessageRecommender.getCountOfTimerStarted());
602 
603         when(mServiceState2.getState()).thenReturn(unavailableServiceState);
604         mTestSOSMessageRecommender.sendServiceStateChangedEvent();
605         processAllMessages();
606         assertEquals(2, mTestSOSMessageRecommender.getCountOfTimerStarted());
607         assertTrue(mTestSOSMessageRecommender.isTimerStarted());
608 
609         // Move Location service to emergency mode
610         mTestSOSMessageRecommender.onEmergencyCallConnectionStateChanged(
611                 mTestConnection.getTelecomCallId(), Connection.STATE_DIALING);
612         processAllMessages();
613         assertNotNull(mTestSOSMessageRecommender.isSatelliteAllowedCallback);
614 
615         // Wait for the timeout to expires
616         mTestSOSMessageRecommender.isSatelliteAllowedCallback.onResult(true);
617         moveTimeForward(TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS);
618         processAllMessages();
619 
620         assertTrue(mTestConnection.isEventSent(TelephonyManager.EVENT_DISPLAY_EMERGENCY_MESSAGE,
621                 EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911, DEFAULT_SATELLITE_MESSAGING_PACKAGE,
622                 DEFAULT_SATELLITE_MESSAGING_CLASS, DEFAULT_T911_HANDOVER_INTENT_ACTION));
623         assertUnregisterForStateChangedEventsTriggered(mPhone, 1, 1);
624         assertUnregisterForStateChangedEventsTriggered(mPhone2, 1, 1);
625         assertEquals(0, mTestSOSMessageRecommender.getCountOfTimerStarted());
626         assertFalse(mTestSOSMessageRecommender.isTimerStarted());
627     }
628 
assertRegisterForStateChangedEventsTriggered(Phone phone, int registerForProvisionCount, int registerForCellularCount)629     private void assertRegisterForStateChangedEventsTriggered(Phone phone,
630             int registerForProvisionCount, int registerForCellularCount) {
631         assertEquals(registerForProvisionCount,
632                 mTestSatelliteController.getRegisterForSatelliteProvisionStateChangedCalls());
633         verify(phone, times(registerForCellularCount))
634                 .registerForServiceStateChanged(any(), anyInt(), any());
635     }
636 
assertUnregisterForStateChangedEventsTriggered( Phone phone, int unregisterForProvisionCount, int unregisterForCellularCount)637     private void assertUnregisterForStateChangedEventsTriggered(
638             Phone phone, int unregisterForProvisionCount, int unregisterForCellularCount) {
639         assertEquals(unregisterForProvisionCount,
640                 mTestSatelliteController.getUnregisterForSatelliteProvisionStateChangedCalls());
641         verify(phone, times(unregisterForCellularCount)).unregisterForServiceStateChanged(any());
642     }
643 
644     private static class TestSatelliteController extends SatelliteController {
645 
646         private static final String TAG = "TestSatelliteController";
647         private final Map<Integer, Set<ISatelliteProvisionStateCallback>>
648                 mProvisionStateChangedCallbacks;
649         private int mRegisterForSatelliteProvisionStateChangedCalls = 0;
650         private int mUnregisterForSatelliteProvisionStateChangedCalls = 0;
651         private Boolean mIsSatelliteViaOemProvisioned = true;
652         private boolean mIsSatelliteConnectedViaCarrierWithinHysteresisTime = true;
653         public boolean isOemEnabledSatelliteSupported = true;
654         public boolean isCarrierEnabledSatelliteSupported = true;
655         public boolean isSatelliteEmergencyMessagingSupportedViaCarrier = true;
656         public long carrierEmergencyCallWaitForConnectionTimeoutMillis =
657                 TEST_EMERGENCY_CALL_TO_SOS_MSG_HYSTERESIS_TIMEOUT_MILLIS;
658 
659         /**
660          * Create a SatelliteController to act as a backend service of
661          * {@link SatelliteManager}
662          *
663          * @param context The Context for the SatelliteController.
664          */
TestSatelliteController( Context context, Looper looper, FeatureFlags featureFlags)665         protected TestSatelliteController(
666                 Context context, Looper looper, FeatureFlags featureFlags) {
667             super(context, looper, featureFlags);
668             mProvisionStateChangedCallbacks = new HashMap<>();
669         }
670 
671         @Override
isSatelliteViaOemProvisioned()672         public Boolean isSatelliteViaOemProvisioned() {
673             return mIsSatelliteViaOemProvisioned;
674         }
675 
676         @Override
isSatelliteSupportedViaOem()677         public boolean isSatelliteSupportedViaOem() {
678             return isOemEnabledSatelliteSupported;
679         }
680 
681         @Override
isSatelliteSupportedViaCarrier()682         public boolean isSatelliteSupportedViaCarrier() {
683             return isCarrierEnabledSatelliteSupported;
684         }
685 
686         @Override
registerForSatelliteProvisionStateChanged( int subId, @NonNull ISatelliteProvisionStateCallback callback)687         @SatelliteManager.SatelliteResult public int registerForSatelliteProvisionStateChanged(
688                 int subId, @NonNull ISatelliteProvisionStateCallback callback) {
689             mRegisterForSatelliteProvisionStateChangedCalls++;
690             Set<ISatelliteProvisionStateCallback> perSubscriptionCallbacks =
691                     mProvisionStateChangedCallbacks.getOrDefault(subId, new HashSet<>());
692             perSubscriptionCallbacks.add(callback);
693             mProvisionStateChangedCallbacks.put(subId, perSubscriptionCallbacks);
694             return SatelliteManager.SATELLITE_RESULT_SUCCESS;
695         }
696 
697         @Override
unregisterForSatelliteProvisionStateChanged( int subId, @NonNull ISatelliteProvisionStateCallback callback)698         public void unregisterForSatelliteProvisionStateChanged(
699                 int subId, @NonNull ISatelliteProvisionStateCallback callback) {
700             mUnregisterForSatelliteProvisionStateChangedCalls++;
701             Set<ISatelliteProvisionStateCallback> perSubscriptionCallbacks =
702                     mProvisionStateChangedCallbacks.get(subId);
703             if (perSubscriptionCallbacks != null) {
704                 perSubscriptionCallbacks.remove(callback);
705             }
706         }
707 
708         @Override
isSatelliteConnectedViaCarrierWithinHysteresisTime()709         public boolean isSatelliteConnectedViaCarrierWithinHysteresisTime() {
710             return mIsSatelliteConnectedViaCarrierWithinHysteresisTime;
711         }
712 
713         @Override
getEnforcedEmergencyCallToSatelliteHandoverType()714         protected int getEnforcedEmergencyCallToSatelliteHandoverType() {
715             return INVALID_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE;
716         }
717 
718         @Override
isSatelliteEmergencyMessagingSupportedViaCarrier()719         public boolean isSatelliteEmergencyMessagingSupportedViaCarrier() {
720             return isSatelliteEmergencyMessagingSupportedViaCarrier;
721         }
722 
723         @Override
getCarrierEmergencyCallWaitForConnectionTimeoutMillis()724         public long getCarrierEmergencyCallWaitForConnectionTimeoutMillis() {
725             return carrierEmergencyCallWaitForConnectionTimeoutMillis;
726         }
727 
setSatelliteConnectedViaCarrierWithinHysteresisTime( boolean connectedViaCarrier)728         public void setSatelliteConnectedViaCarrierWithinHysteresisTime(
729                 boolean connectedViaCarrier) {
730             mIsSatelliteConnectedViaCarrierWithinHysteresisTime = connectedViaCarrier;
731         }
732 
getRegisterForSatelliteProvisionStateChangedCalls()733         public int getRegisterForSatelliteProvisionStateChangedCalls() {
734             return mRegisterForSatelliteProvisionStateChangedCalls;
735         }
736 
getUnregisterForSatelliteProvisionStateChangedCalls()737         public int getUnregisterForSatelliteProvisionStateChangedCalls() {
738             return mUnregisterForSatelliteProvisionStateChangedCalls;
739         }
740 
setIsSatelliteViaOemProvisioned(boolean provisioned)741         public void setIsSatelliteViaOemProvisioned(boolean provisioned) {
742             mIsSatelliteViaOemProvisioned = provisioned;
743         }
744 
sendProvisionStateChangedEvent(int subId, boolean provisioned)745         public void sendProvisionStateChangedEvent(int subId, boolean provisioned) {
746             mIsSatelliteViaOemProvisioned = provisioned;
747             Set<ISatelliteProvisionStateCallback> perSubscriptionCallbacks =
748                     mProvisionStateChangedCallbacks.get(subId);
749             if (perSubscriptionCallbacks != null) {
750                 for (ISatelliteProvisionStateCallback callback : perSubscriptionCallbacks) {
751                     try {
752                         callback.onSatelliteProvisionStateChanged(provisioned);
753                     } catch (RemoteException ex) {
754                         Log.e(TAG, "sendProvisionStateChangedEvent: ex=" + ex);
755                     }
756                 }
757             }
758         }
759     }
760 
761     private static class TestImsManager extends ImsManager {
762 
763         private final List<RegistrationManager.RegistrationCallback> mCallbacks;
764         private int mAddRegistrationCallbackCalls = 0;
765         private int mRemoveRegistrationListenerCalls = 0;
766 
767         /**
768          * Used for testing only to inject dependencies.
769          */
TestImsManager(Context context, int phoneId, MmTelFeatureConnectionFactory factory, SubscriptionManagerProxy subManagerProxy, SettingsProxy settingsProxy, BinderCacheManager binderCacheManager)770         TestImsManager(Context context, int phoneId, MmTelFeatureConnectionFactory factory,
771                 SubscriptionManagerProxy subManagerProxy, SettingsProxy settingsProxy,
772                 BinderCacheManager binderCacheManager) {
773             super(context, phoneId, factory, subManagerProxy, settingsProxy, binderCacheManager);
774             mCallbacks = new ArrayList<>();
775         }
776 
777         @Override
addRegistrationCallback(RegistrationManager.RegistrationCallback callback, Executor executor)778         public void addRegistrationCallback(RegistrationManager.RegistrationCallback callback,
779                 Executor executor)
780                 throws ImsException {
781             mAddRegistrationCallbackCalls++;
782 
783             if (callback == null) {
784                 throw new NullPointerException("registration callback can't be null");
785             }
786             if (executor == null) {
787                 throw new NullPointerException("registration executor can't be null");
788             }
789 
790             callback.setExecutor(executor);
791             if (!mCallbacks.contains(callback)) {
792                 mCallbacks.add(callback);
793             }
794         }
795 
796         @Override
removeRegistrationListener(RegistrationManager.RegistrationCallback callback)797         public void removeRegistrationListener(RegistrationManager.RegistrationCallback callback) {
798             mRemoveRegistrationListenerCalls++;
799 
800             if (callback == null) {
801                 throw new NullPointerException("registration callback can't be null");
802             }
803             mCallbacks.remove(callback);
804         }
805 
getAddRegistrationCallbackCalls()806         public int getAddRegistrationCallbackCalls() {
807             return mAddRegistrationCallbackCalls;
808         }
809 
getRemoveRegistrationListenerCalls()810         public int getRemoveRegistrationListenerCalls() {
811             return mRemoveRegistrationListenerCalls;
812         }
813 
sendImsRegistrationStateChangedEvent(int callbackIndex, boolean registered)814         public void sendImsRegistrationStateChangedEvent(int callbackIndex, boolean registered) {
815             if (callbackIndex < 0 || callbackIndex >= mCallbacks.size()) {
816                 throw new IndexOutOfBoundsException("sendImsRegistrationStateChangedEvent: invalid"
817                         + "callbackIndex=" + callbackIndex
818                         + ", mCallbacks.size=" + mCallbacks.size());
819             }
820             RegistrationManager.RegistrationCallback callback = mCallbacks.get(callbackIndex);
821             if (registered) {
822                 callback.onRegistered(null);
823             } else {
824                 callback.onUnregistered(null);
825             }
826         }
827     }
828 
829     private static class TestSOSMessageRecommender extends SatelliteSOSMessageRecommender {
830         public OutcomeReceiver<Boolean, SatelliteManager.SatelliteException>
831                 isSatelliteAllowedCallback = null;
832         private ComponentName mSmsAppComponent = new ComponentName(
833                 DEFAULT_SATELLITE_MESSAGING_PACKAGE, DEFAULT_SATELLITE_MESSAGING_CLASS);
834 
835         /**
836          * Create an instance of SatelliteSOSMessageRecommender.
837          *
838          * @param looper              The looper used with the handler of this class.
839          * @param satelliteController The SatelliteController singleton instance.
840          * @param imsManager          The ImsManager instance associated with the phone, which is
841          *                            used for making the emergency call. This argument is not
842          *                            null only in unit tests.
843          */
TestSOSMessageRecommender(Context context, Looper looper, SatelliteController satelliteController, ImsManager imsManager)844         TestSOSMessageRecommender(Context context, Looper looper,
845                 SatelliteController satelliteController, ImsManager imsManager) {
846             super(context, looper, satelliteController, imsManager);
847         }
848 
849         @Override
getDefaultSmsApp()850         protected ComponentName getDefaultSmsApp() {
851             return mSmsAppComponent;
852         }
853 
854         @Override
requestIsSatelliteCommunicationAllowedForCurrentLocation( @onNull OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> callback)855         protected void requestIsSatelliteCommunicationAllowedForCurrentLocation(
856                 @NonNull OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> callback) {
857             logd("requestIsSatelliteCommunicationAllowedForCurrentLocation: callback="
858                     + callback);
859             isSatelliteAllowedCallback = callback;
860         }
861 
isTimerStarted()862         public boolean isTimerStarted() {
863             return hasMessages(EVENT_TIME_OUT);
864         }
865 
getCountOfTimerStarted()866         public int getCountOfTimerStarted() {
867             return mCountOfTimerStarted;
868         }
869 
sendServiceStateChangedEvent()870         public void sendServiceStateChangedEvent() {
871             sendMessage(obtainMessage(EVENT_SERVICE_STATE_CHANGED));
872         }
873 
getTimeOutMillis()874         public long getTimeOutMillis() {
875             return mTimeoutMillis;
876         }
877     }
878 
879     private static class TestConnection extends Connection {
880         private String mSentEvent = null;
881         private Bundle mExtras = null;
TestConnection(String callId)882         TestConnection(String callId) {
883             setTelecomCallId(callId);
884         }
885 
886         @Override
sendConnectionEvent(String event, Bundle extras)887         public void sendConnectionEvent(String event, Bundle extras) {
888             mSentEvent = event;
889             mExtras = extras;
890         }
891 
isEventSent(String event, int handoverType, String packageName, String className, String action)892         public boolean isEventSent(String event, int handoverType, String packageName,
893                 String className, String action) {
894             if (mSentEvent == null || mExtras == null) {
895                 return false;
896             }
897 
898             PendingIntent pendingIntent = mExtras.getParcelable(
899                     EXTRA_EMERGENCY_CALL_TO_SATELLITE_LAUNCH_INTENT, PendingIntent.class);
900             Intent intent = pendingIntent.getIntent();
901             if (!TextUtils.equals(event, mSentEvent) || handoverType != mExtras.getInt(
902                     EXTRA_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE)
903                     || !TextUtils.equals(packageName, intent.getComponent().getPackageName())
904                     || !TextUtils.equals(className, intent.getComponent().getClassName())
905                     || !TextUtils.equals(action, intent.getAction())) {
906                 return false;
907             }
908             return true;
909         }
910 
isEventWithoutLaunchIntentSent(String event, int handoverType)911         public boolean isEventWithoutLaunchIntentSent(String event, int handoverType) {
912             if (mSentEvent == null || mExtras == null) {
913                 return false;
914             }
915 
916             PendingIntent pendingIntent = mExtras.getParcelable(
917                     EXTRA_EMERGENCY_CALL_TO_SATELLITE_LAUNCH_INTENT, PendingIntent.class);
918             if (!TextUtils.equals(event, mSentEvent) || handoverType != mExtras.getInt(
919                     EXTRA_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE) || pendingIntent != null) {
920                 return false;
921             }
922 
923             return true;
924         }
925 
isEventSent(String event)926         public boolean isEventSent(String event) {
927             if (mSentEvent == null) {
928                 return false;
929             }
930             if (!TextUtils.equals(event, mSentEvent)) {
931                 return false;
932             }
933             return true;
934         }
935     }
936 }
937