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.services.telephony.domainselection;
18 
19 import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_CROSS_STACK_REDIAL_TIMER_SEC_INT;
20 import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT;
21 import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_START_QUICK_CROSS_STACK_REDIAL_TIMER_WHEN_REGISTERED_BOOL;
22 import static android.telephony.CarrierConfigManager.ImsEmergency.REDIAL_TIMER_DISABLED;
23 import static android.telephony.PreciseDisconnectCause.EMERGENCY_PERM_FAILURE;
24 import static android.telephony.PreciseDisconnectCause.EMERGENCY_TEMP_FAILURE;
25 
26 import static com.android.services.telephony.domainselection.CrossSimRedialingController.MSG_CROSS_STACK_TIMEOUT;
27 import static com.android.services.telephony.domainselection.CrossSimRedialingController.MSG_QUICK_CROSS_STACK_TIMEOUT;
28 
29 import static junit.framework.Assert.assertFalse;
30 import static junit.framework.Assert.assertNotNull;
31 import static junit.framework.Assert.assertTrue;
32 
33 import static org.mockito.ArgumentMatchers.anyInt;
34 import static org.mockito.ArgumentMatchers.anyString;
35 import static org.mockito.Mockito.doReturn;
36 import static org.mockito.Mockito.times;
37 import static org.mockito.Mockito.verify;
38 import static org.mockito.Mockito.when;
39 
40 import android.content.Context;
41 import android.os.HandlerThread;
42 import android.os.Looper;
43 import android.os.PersistableBundle;
44 import android.telephony.CarrierConfigManager;
45 import android.telephony.TelephonyManager;
46 import android.telephony.emergency.EmergencyNumber;
47 import android.testing.TestableLooper;
48 import android.util.Log;
49 
50 import com.android.TestContext;
51 
52 import org.junit.After;
53 import org.junit.Before;
54 import org.junit.Test;
55 import org.mockito.ArgumentMatchers;
56 import org.mockito.Mock;
57 import org.mockito.MockitoAnnotations;
58 
59 import java.util.ArrayList;
60 import java.util.HashMap;
61 import java.util.List;
62 import java.util.Map;
63 
64 /**
65  * Unit tests for CrossSimRedialingController
66  */
67 public class CrossSimRedialingControllerTest {
68     private static final String TAG = "CrossSimRedialingControllerTest";
69 
70     private static final int SLOT_0 = 0;
71     private static final int SLOT_1 = 1;
72 
73     private static final String TELECOM_CALL_ID1 = "TC1";
74     private static final String TEST_EMERGENCY_NUMBER = "911";
75 
76     @Mock private EmergencyCallDomainSelector mEcds;
77     @Mock private CrossSimRedialingController.EmergencyNumberHelper mEmergencyNumberHelper;
78 
79     private Context mContext;
80 
81     private HandlerThread mHandlerThread;
82     private TestableLooper mLooper;
83     private CrossSimRedialingController mCsrController;
84     private CarrierConfigManager mCarrierConfigManager;
85     private TelephonyManager mTelephonyManager;
86 
87     @Before
setUp()88     public void setUp() throws Exception {
89         MockitoAnnotations.initMocks(this);
90         mContext = new TestContext() {
91             @Override
92             public String getSystemServiceName(Class<?> serviceClass) {
93                 if (serviceClass == TelephonyManager.class) {
94                     return Context.TELEPHONY_SERVICE;
95                 } else if (serviceClass == CarrierConfigManager.class) {
96                     return Context.CARRIER_CONFIG_SERVICE;
97                 }
98                 return super.getSystemServiceName(serviceClass);
99             }
100 
101             @Override
102             public String getOpPackageName() {
103                 return "";
104             }
105         };
106 
107         if (Looper.myLooper() == null) {
108             Looper.prepare();
109         }
110 
111         mHandlerThread = new HandlerThread("CrossSimRedialingControllerTest");
112         mHandlerThread.start();
113 
114         try {
115             mLooper = new TestableLooper(mHandlerThread.getLooper());
116         } catch (Exception e) {
117             logd("Unable to create looper from handler.");
118         }
119 
120         mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
121         when(mTelephonyManager.createForSubscriptionId(anyInt()))
122                 .thenReturn(mTelephonyManager);
123         when(mTelephonyManager.getNetworkCountryIso()).thenReturn("");
124         doReturn(2).when(mTelephonyManager).getActiveModemCount();
125         doReturn(TelephonyManager.SIM_STATE_READY)
126                 .when(mTelephonyManager).getSimState(anyInt());
127 
128         mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
129         doReturn(getDefaultPersistableBundle()).when(mCarrierConfigManager)
130                 .getConfigForSubId(anyInt(), ArgumentMatchers.<String>any());
131 
132         doReturn(true).when(mEmergencyNumberHelper).isEmergencyNumber(anyInt(), anyString());
133 
134         doReturn(SLOT_0).when(mEcds).getSlotId();
135     }
136 
137     @After
tearDown()138     public void tearDown() throws Exception {
139         if (mCsrController != null) {
140             mCsrController.destroy();
141             mCsrController = null;
142         }
143 
144         if (mLooper != null) {
145             mLooper.destroy();
146             mLooper = null;
147         }
148     }
149 
150     @Test
testDefaultStartTimerInService()151     public void testDefaultStartTimerInService() throws Exception {
152         createController();
153 
154         boolean inService = true;
155         boolean inRoaming = false;
156         mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
157                 TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
158 
159         assertFalse(mCsrController.hasMessages(MSG_QUICK_CROSS_STACK_TIMEOUT));
160         assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
161 
162         mCsrController.sendEmptyMessage(MSG_CROSS_STACK_TIMEOUT);
163         processAllMessages();
164 
165         verify(mEcds).notifyCrossStackTimerExpired();
166     }
167 
168     @Test
testDefaultStartTimerInServiceRoaming()169     public void testDefaultStartTimerInServiceRoaming() throws Exception {
170         createController();
171 
172         boolean inService = true;
173         boolean inRoaming = true;
174         mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
175                 TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
176 
177         assertFalse(mCsrController.hasMessages(MSG_QUICK_CROSS_STACK_TIMEOUT));
178         assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
179     }
180 
181     @Test
testDefaultStartTimerOutOfService()182     public void testDefaultStartTimerOutOfService() throws Exception {
183         createController();
184 
185         boolean inService = false;
186         boolean inRoaming = false;
187         mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
188                 TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
189 
190         assertFalse(mCsrController.hasMessages(MSG_QUICK_CROSS_STACK_TIMEOUT));
191         assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
192     }
193 
194     @Test
testDefaultStartTimerOutOfServiceRoaming()195     public void testDefaultStartTimerOutOfServiceRoaming() throws Exception {
196         createController();
197 
198         boolean inService = false;
199         boolean inRoaming = true;
200         mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
201                 TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
202 
203         assertFalse(mCsrController.hasMessages(MSG_QUICK_CROSS_STACK_TIMEOUT));
204         assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
205     }
206 
207     @Test
testQuickStartTimerInService()208     public void testQuickStartTimerInService() throws Exception {
209         PersistableBundle bundle = getDefaultPersistableBundle();
210         bundle.putInt(KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT, 3);
211         doReturn(bundle).when(mCarrierConfigManager)
212                 .getConfigForSubId(anyInt(), ArgumentMatchers.<String>any());
213 
214         createController();
215 
216         boolean inService = true;
217         boolean inRoaming = false;
218         mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
219                 TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
220 
221         assertTrue(mCsrController.hasMessages(MSG_QUICK_CROSS_STACK_TIMEOUT));
222         assertFalse(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
223 
224         mCsrController.sendEmptyMessage(MSG_QUICK_CROSS_STACK_TIMEOUT);
225         processAllMessages();
226 
227         verify(mEcds).notifyCrossStackTimerExpired();
228     }
229 
230     @Test
testQuickStartTimerInServiceRoaming()231     public void testQuickStartTimerInServiceRoaming() throws Exception {
232         PersistableBundle bundle = getDefaultPersistableBundle();
233         bundle.putInt(KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT, 3);
234         doReturn(bundle).when(mCarrierConfigManager)
235                 .getConfigForSubId(anyInt(), ArgumentMatchers.<String>any());
236 
237         createController();
238 
239         boolean inService = true;
240         boolean inRoaming = true;
241         mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
242                 TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
243 
244         assertFalse(mCsrController.hasMessages(MSG_QUICK_CROSS_STACK_TIMEOUT));
245         assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
246     }
247 
248     @Test
testQuickStartTimerOutOfService()249     public void testQuickStartTimerOutOfService() throws Exception {
250         PersistableBundle bundle = getDefaultPersistableBundle();
251         bundle.putInt(KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT, 3);
252         doReturn(bundle).when(mCarrierConfigManager)
253                 .getConfigForSubId(anyInt(), ArgumentMatchers.<String>any());
254 
255         createController();
256 
257         boolean inService = false;
258         boolean inRoaming = false;
259         mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
260                 TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
261 
262         assertTrue(mCsrController.hasMessages(MSG_QUICK_CROSS_STACK_TIMEOUT));
263         assertFalse(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
264     }
265 
266     @Test
testQuickStartTimerOutOfServiceRoaming()267     public void testQuickStartTimerOutOfServiceRoaming() throws Exception {
268         PersistableBundle bundle = getDefaultPersistableBundle();
269         bundle.putInt(KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT, 3);
270         doReturn(bundle).when(mCarrierConfigManager)
271                 .getConfigForSubId(anyInt(), ArgumentMatchers.<String>any());
272 
273         createController();
274 
275         boolean inService = false;
276         boolean inRoaming = true;
277         mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
278                 TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
279 
280         assertFalse(mCsrController.hasMessages(MSG_QUICK_CROSS_STACK_TIMEOUT));
281         assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
282     }
283 
284     @Test
testNoNormalStartTimerInService()285     public void testNoNormalStartTimerInService() throws Exception {
286         PersistableBundle bundle = getDefaultPersistableBundle();
287         bundle.putInt(KEY_CROSS_STACK_REDIAL_TIMER_SEC_INT, REDIAL_TIMER_DISABLED);
288         doReturn(bundle).when(mCarrierConfigManager)
289                 .getConfigForSubId(anyInt(), ArgumentMatchers.<String>any());
290 
291         createController();
292 
293         boolean inService = true;
294         boolean inRoaming = false;
295         mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
296                 TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
297 
298         assertFalse(mCsrController.hasMessages(MSG_QUICK_CROSS_STACK_TIMEOUT));
299         assertFalse(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
300     }
301 
302     @Test
testQuickWhenInServiceStartTimerOutOfService()303     public void testQuickWhenInServiceStartTimerOutOfService() throws Exception {
304         PersistableBundle bundle = getDefaultPersistableBundle();
305         bundle.putInt(KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT, 3);
306         bundle.putBoolean(KEY_START_QUICK_CROSS_STACK_REDIAL_TIMER_WHEN_REGISTERED_BOOL, true);
307         doReturn(bundle).when(mCarrierConfigManager)
308                 .getConfigForSubId(anyInt(), ArgumentMatchers.<String>any());
309 
310         createController();
311 
312         boolean inService = false;
313         boolean inRoaming = false;
314         mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
315                 TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
316 
317         assertFalse(mCsrController.hasMessages(MSG_QUICK_CROSS_STACK_TIMEOUT));
318         assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
319     }
320 
321     @Test
testQuickNoNormalStartTimerInService()322     public void testQuickNoNormalStartTimerInService() throws Exception {
323         PersistableBundle bundle = getDefaultPersistableBundle();
324         bundle.putInt(KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT, 3);
325         bundle.putInt(KEY_CROSS_STACK_REDIAL_TIMER_SEC_INT, REDIAL_TIMER_DISABLED);
326         doReturn(bundle).when(mCarrierConfigManager)
327                 .getConfigForSubId(anyInt(), ArgumentMatchers.<String>any());
328 
329         createController();
330 
331         boolean inService = true;
332         boolean inRoaming = false;
333         mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
334                 TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
335 
336         assertTrue(mCsrController.hasMessages(MSG_QUICK_CROSS_STACK_TIMEOUT));
337         assertFalse(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
338     }
339 
340     @Test
testDefaultSlot0ThenSlot1()341     public void testDefaultSlot0ThenSlot1() throws Exception {
342         createController();
343 
344         boolean inService = true;
345         boolean inRoaming = false;
346         mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
347                 TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
348 
349         assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
350 
351         mCsrController.removeMessages(MSG_CROSS_STACK_TIMEOUT);
352         assertFalse(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
353 
354         doReturn(SLOT_1).when(mEcds).getSlotId();
355         mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
356                 TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
357 
358         assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
359     }
360 
361     @Test
testDefaultSlot0PermThenSlot1Timeout()362     public void testDefaultSlot0PermThenSlot1Timeout() throws Exception {
363         createController();
364 
365         boolean inService = true;
366         boolean inRoaming = false;
367         mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
368                 TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
369 
370         assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
371 
372         mCsrController.notifyCallFailure(EMERGENCY_PERM_FAILURE);
373         mCsrController.stopTimer();
374         assertFalse(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
375 
376         doReturn(SLOT_1).when(mEcds).getSlotId();
377         mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
378                 TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
379 
380         assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
381 
382         mCsrController.sendEmptyMessage(MSG_CROSS_STACK_TIMEOUT);
383         processAllMessages();
384 
385         verify(mEcds, times(0)).notifyCrossStackTimerExpired();
386     }
387 
388     @Test
testDefaultSlot0TempThenSlot1Timeout()389     public void testDefaultSlot0TempThenSlot1Timeout() throws Exception {
390         createController();
391 
392         boolean inService = true;
393         boolean inRoaming = false;
394         mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
395                 TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
396 
397         assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
398 
399         mCsrController.notifyCallFailure(EMERGENCY_TEMP_FAILURE);
400         mCsrController.stopTimer();
401         assertFalse(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
402 
403         doReturn(SLOT_1).when(mEcds).getSlotId();
404         mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
405                 TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
406 
407         assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
408 
409         mCsrController.sendEmptyMessage(MSG_CROSS_STACK_TIMEOUT);
410         processAllMessages();
411 
412         verify(mEcds).notifyCrossStackTimerExpired();
413     }
414 
415     @Test
testDefaultSlot0TempThenSlot1TimeoutNotEmergencyNumber()416     public void testDefaultSlot0TempThenSlot1TimeoutNotEmergencyNumber() throws Exception {
417         createController();
418 
419         boolean inService = true;
420         boolean inRoaming = false;
421         mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
422                 TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
423 
424         assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
425 
426         mCsrController.notifyCallFailure(EMERGENCY_TEMP_FAILURE);
427         mCsrController.stopTimer();
428         assertFalse(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
429 
430         doReturn(SLOT_1).when(mEcds).getSlotId();
431         mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
432                 TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
433 
434         assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
435 
436         doReturn(false).when(mEmergencyNumberHelper).isEmergencyNumber(anyInt(), anyString());
437         mCsrController.sendEmptyMessage(MSG_CROSS_STACK_TIMEOUT);
438         processAllMessages();
439 
440         verify(mEcds, times(0)).notifyCrossStackTimerExpired();
441     }
442 
443     @Test
testDefaultSlot0TempThenSlot1TimeoutPinLocked()444     public void testDefaultSlot0TempThenSlot1TimeoutPinLocked() throws Exception {
445         createController();
446 
447         boolean inService = true;
448         boolean inRoaming = false;
449         mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
450                 TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
451 
452         assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
453 
454         mCsrController.notifyCallFailure(EMERGENCY_TEMP_FAILURE);
455         mCsrController.stopTimer();
456         assertFalse(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
457 
458         doReturn(SLOT_1).when(mEcds).getSlotId();
459         mCsrController.startTimer(mContext, mEcds, TELECOM_CALL_ID1,
460                 TEST_EMERGENCY_NUMBER, inService, inRoaming, 2);
461 
462         assertTrue(mCsrController.hasMessages(MSG_CROSS_STACK_TIMEOUT));
463 
464         doReturn(TelephonyManager.SIM_STATE_PIN_REQUIRED)
465                 .when(mTelephonyManager).getSimState(anyInt());
466         mCsrController.sendEmptyMessage(MSG_CROSS_STACK_TIMEOUT);
467         processAllMessages();
468 
469         verify(mEcds, times(0)).notifyCrossStackTimerExpired();
470     }
471 
472     @Test
testEmergencyNumberHelper()473     public void testEmergencyNumberHelper() throws Exception {
474         mCsrController = new CrossSimRedialingController(mContext,
475                 mHandlerThread.getLooper());
476 
477         CrossSimRedialingController.EmergencyNumberHelper helper =
478                 mCsrController.getEmergencyNumberHelper();
479 
480         assertNotNull(helper);
481 
482         EmergencyNumber num1 = new EmergencyNumber(TEST_EMERGENCY_NUMBER, "us", "",
483                 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE, new ArrayList<String>(),
484                 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
485                 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
486 
487         EmergencyNumber num2 = new EmergencyNumber("119", "jp", "",
488                 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE, new ArrayList<String>(),
489                 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
490                 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
491 
492         Map<Integer, List<EmergencyNumber>> lists = new HashMap<>();
493         List<EmergencyNumber> list = new ArrayList<>();
494         list.add(num1);
495         lists.put(1, list);
496 
497         list = new ArrayList<>();
498         list.add(num2);
499         lists.put(2, list);
500 
501         doReturn(lists).when(mTelephonyManager).getEmergencyNumberList();
502 
503         assertTrue(helper.isEmergencyNumber(1, TEST_EMERGENCY_NUMBER));
504         assertFalse(helper.isEmergencyNumber(2, TEST_EMERGENCY_NUMBER));
505         assertFalse(helper.isEmergencyNumber(3, TEST_EMERGENCY_NUMBER));
506     }
507 
createController()508     private void createController() throws Exception {
509         mCsrController = new CrossSimRedialingController(mContext,
510                 mHandlerThread.getLooper(), mEmergencyNumberHelper);
511     }
512 
getDefaultPersistableBundle()513     private static PersistableBundle getDefaultPersistableBundle() {
514         return getPersistableBundle(0, 120, false);
515     }
516 
getPersistableBundle( int quickTimer, int timer, boolean startQuickInService)517     private static PersistableBundle getPersistableBundle(
518             int quickTimer, int timer, boolean startQuickInService) {
519         PersistableBundle bundle  = new PersistableBundle();
520         bundle.putInt(KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT, quickTimer);
521         bundle.putInt(KEY_CROSS_STACK_REDIAL_TIMER_SEC_INT, timer);
522         bundle.putBoolean(KEY_START_QUICK_CROSS_STACK_REDIAL_TIMER_WHEN_REGISTERED_BOOL,
523                 startQuickInService);
524 
525         return bundle;
526     }
527 
processAllMessages()528     private void processAllMessages() {
529         while (!mLooper.getLooper().getQueue().isIdle()) {
530             mLooper.processAllMessages();
531         }
532     }
533 
logd(String str)534     private static void logd(String str) {
535         Log.d(TAG, str);
536     }
537 }
538