1 /*
2  * Copyright (C) 2019 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 android.telephony.ims.cts;
18 
19 import static junit.framework.TestCase.assertEquals;
20 
21 import static org.junit.Assert.assertNotNull;
22 import static org.junit.Assert.fail;
23 
24 import android.content.BroadcastReceiver;
25 import android.content.Context;
26 import android.content.Intent;
27 import android.content.IntentFilter;
28 import android.database.ContentObserver;
29 import android.net.Uri;
30 import android.os.Handler;
31 import android.os.Looper;
32 import android.os.PersistableBundle;
33 import android.telephony.AccessNetworkConstants;
34 import android.telephony.CarrierConfigManager;
35 import android.telephony.SubscriptionManager;
36 import android.telephony.ims.ImsException;
37 import android.telephony.ims.ImsManager;
38 import android.telephony.ims.ImsMmTelManager;
39 import android.telephony.ims.feature.MmTelFeature;
40 
41 import androidx.test.ext.junit.runners.AndroidJUnit4;
42 import androidx.test.platform.app.InstrumentationRegistry;
43 
44 import com.android.compatibility.common.util.ShellIdentityUtils;
45 
46 import org.junit.AfterClass;
47 import org.junit.Before;
48 import org.junit.BeforeClass;
49 import org.junit.Test;
50 import org.junit.runner.RunWith;
51 
52 import java.util.concurrent.CountDownLatch;
53 import java.util.concurrent.LinkedBlockingQueue;
54 import java.util.concurrent.TimeUnit;
55 
56 @RunWith(AndroidJUnit4.class)
57 public class ImsMmTelManagerTest {
58 
59     // Copied from CarrierConfigManager, since these keys is inappropriately marked as @hide
60     private static final String KEY_CARRIER_VOLTE_OVERRIDE_WFC_PROVISIONING_BOOL =
61             "carrier_volte_override_wfc_provisioning_bool";
62     private static final String KEY_EDITABLE_WFC_MODE_BOOL = "editable_wfc_mode_bool";
63     private static final String KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL =
64             "use_wfc_home_network_mode_in_roaming_network_bool";
65     private static final String KEY_EDITABLE_WFC_ROAMING_MODE_BOOL =
66             "editable_wfc_roaming_mode_bool";
67 
68     private static int sTestSub = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
69     private static Handler sHandler;
70     private static CarrierConfigReceiver sReceiver;
71 
72     private static class CarrierConfigReceiver extends BroadcastReceiver {
73         private CountDownLatch mLatch = new CountDownLatch(1);
74         private final int mSubId;
75 
CarrierConfigReceiver(int subId)76         CarrierConfigReceiver(int subId) {
77             mSubId = subId;
78         }
79 
80         @Override
onReceive(Context context, Intent intent)81         public void onReceive(Context context, Intent intent) {
82             if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(intent.getAction())) {
83                 int subId = intent.getIntExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, -1);
84                 if (mSubId == subId) {
85                     mLatch.countDown();
86                 }
87             }
88         }
89 
clearQueue()90         void clearQueue() {
91             mLatch = new CountDownLatch(1);
92         }
93 
waitForCarrierConfigChanged()94         void waitForCarrierConfigChanged() throws Exception {
95             mLatch.await(5000, TimeUnit.MILLISECONDS);
96         }
97     }
98 
99     @BeforeClass
beforeAllTests()100     public static void beforeAllTests() {
101         if (!ImsUtils.shouldTestImsService()) {
102             return;
103         }
104 
105         sTestSub = ImsUtils.getPreferredActiveSubId();
106 
107         if (Looper.getMainLooper() == null) {
108             Looper.prepareMainLooper();
109         }
110         sHandler = new Handler(Looper.getMainLooper());
111 
112         sReceiver = new CarrierConfigReceiver(sTestSub);
113         IntentFilter filter = new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
114         // ACTION_CARRIER_CONFIG_CHANGED is sticky, so we will get a callback right away.
115         getContext().registerReceiver(sReceiver, filter);
116     }
117 
118     @AfterClass
afterAllTests()119     public static void afterAllTests() {
120         if (!ImsUtils.shouldTestImsService()) {
121             return;
122         }
123 
124         if (sReceiver != null) {
125             getContext().unregisterReceiver(sReceiver);
126             sReceiver = null;
127         }
128     }
129 
130     @Before
beforeTest()131     public void beforeTest() {
132         if (!ImsUtils.shouldTestImsService()) {
133             return;
134         }
135 
136         if (!SubscriptionManager.isValidSubscriptionId(sTestSub)) {
137             fail("This test requires that there is a SIM in the device!");
138         }
139     }
140 
141     @Test
testGetVoWiFiSetting_noPermission()142     public void testGetVoWiFiSetting_noPermission() {
143         try {
144             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
145             ImsMmTelManager mMmTelManager = imsManager.getImsMmTelManager(sTestSub);
146             boolean isEnabled = mMmTelManager.isVoWiFiSettingEnabled();
147             fail("Expected SecurityException for missing permissions");
148         } catch (SecurityException ex) {
149             /* Expected */
150         }
151     }
152 
153     /**
154      * Given the advanced calling setting is editable and not hidden
155      * (see {@link CarrierConfigManager#KEY_EDITABLE_ENHANCED_4G_LTE_BOOL}, and
156      * {@link CarrierConfigManager#KEY_HIDE_ENHANCED_4G_LTE_BOOL}), set the advanced
157      * calling setting and ensure the correct calling setting is returned. Also ensure the
158      * ContentObserver is triggered properly.
159      */
160     @Test
testAdvancedCallingSetting()161     public void testAdvancedCallingSetting() throws Exception {
162         if (!ImsUtils.shouldTestImsService()) {
163             return;
164         }
165         // Ensure advanced calling setting is editable.
166         PersistableBundle bundle = new PersistableBundle();
167         bundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL, true);
168         bundle.putBoolean(CarrierConfigManager.KEY_HIDE_ENHANCED_4G_LTE_BOOL, false);
169         overrideCarrierConfig(bundle);
170         // Register Observer
171         Uri callingUri = Uri.withAppendedPath(
172                 SubscriptionManager.ADVANCED_CALLING_ENABLED_CONTENT_URI, "" + sTestSub);
173         CountDownLatch contentObservedLatch = new CountDownLatch(1);
174         ContentObserver observer = createObserver(callingUri, contentObservedLatch);
175 
176         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
177         ImsMmTelManager mMmTelManager = imsManager.getImsMmTelManager(sTestSub);
178         boolean isEnabled = ShellIdentityUtils.invokeMethodWithShellPermissions(mMmTelManager,
179                 ImsMmTelManager::isAdvancedCallingSettingEnabled);
180         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mMmTelManager,
181                 (m) -> m.setAdvancedCallingSettingEnabled(!isEnabled));
182 
183         waitForLatch(contentObservedLatch, observer);
184         boolean isEnabledResult = ShellIdentityUtils.invokeMethodWithShellPermissions(mMmTelManager,
185                 ImsMmTelManager::isAdvancedCallingSettingEnabled);
186         assertEquals("isAdvancedCallingSettingEnabled does not reflect the new value set by "
187                         + "setAdvancedCallingSettingEnabled", !isEnabled, isEnabledResult);
188 
189         // Set back to default
190         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mMmTelManager,
191                 (m) -> m.setAdvancedCallingSettingEnabled(isEnabled));
192         // restore original carrier config.
193         overrideCarrierConfig(null);
194     }
195 
196     /**
197      * Set the VT setting and ensure it is queried successfully. Also ensure the ContentObserver
198      * is triggered properly.
199      */
200     @Test
testVtSetting()201     public void testVtSetting() throws Exception {
202         if (!ImsUtils.shouldTestImsService()) {
203             return;
204         }
205 
206         // Register Observer
207         Uri callingUri = Uri.withAppendedPath(
208                 SubscriptionManager.VT_ENABLED_CONTENT_URI, "" + sTestSub);
209         CountDownLatch contentObservedLatch = new CountDownLatch(1);
210         ContentObserver observer = createObserver(callingUri, contentObservedLatch);
211 
212         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
213         ImsMmTelManager mMmTelManager = imsManager.getImsMmTelManager(sTestSub);
214         boolean isEnabled = ShellIdentityUtils.invokeMethodWithShellPermissions(mMmTelManager,
215                 ImsMmTelManager::isVtSettingEnabled);
216         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mMmTelManager,
217                 (m) -> m.setVtSettingEnabled(!isEnabled));
218 
219         waitForLatch(contentObservedLatch, observer);
220         boolean isEnabledResult = ShellIdentityUtils.invokeMethodWithShellPermissions(mMmTelManager,
221                 ImsMmTelManager::isVtSettingEnabled);
222         assertEquals("isVtSettingEnabled does not match the value set by setVtSettingEnabled",
223                 !isEnabled, isEnabledResult);
224 
225         // Set back to default
226         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mMmTelManager,
227                 (m) -> m.setVtSettingEnabled(isEnabled));
228     }
229 
230     /**
231      * Set the VoWiFi setting and ensure it is queried successfully. Also ensure the ContentObserver
232      * is triggered properly.
233      */
234     @Test
testVoWiFiSetting()235     public void testVoWiFiSetting() throws Exception {
236         if (!ImsUtils.shouldTestImsService()) {
237             return;
238         }
239 
240         PersistableBundle bundle = new PersistableBundle();
241         // Do not worry about provisioning for this test
242         bundle.putBoolean(KEY_CARRIER_VOLTE_OVERRIDE_WFC_PROVISIONING_BOOL, false);
243         bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, false);
244         overrideCarrierConfig(bundle);
245         // Register Observer
246         Uri callingUri = Uri.withAppendedPath(
247                 SubscriptionManager.WFC_ENABLED_CONTENT_URI, "" + sTestSub);
248         CountDownLatch contentObservedLatch = new CountDownLatch(1);
249         ContentObserver observer = createObserver(callingUri, contentObservedLatch);
250 
251         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
252         ImsMmTelManager mMmTelManager = imsManager.getImsMmTelManager(sTestSub);
253 
254         boolean isEnabled = ShellIdentityUtils.invokeMethodWithShellPermissions(mMmTelManager,
255                 ImsMmTelManager::isVoWiFiSettingEnabled);
256         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mMmTelManager,
257                 (m) -> m.setVoWiFiSettingEnabled(!isEnabled));
258 
259         waitForLatch(contentObservedLatch, observer);
260         boolean isEnabledResult = ShellIdentityUtils.invokeMethodWithShellPermissions(mMmTelManager,
261                 ImsMmTelManager::isVoWiFiSettingEnabled);
262         assertEquals("isVoWiFiSettingEnabled did not match value set by setVoWiFiSettingEnabled",
263                 !isEnabled, isEnabledResult);
264 
265         // Set back to default
266         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mMmTelManager,
267                 (m) -> m.setVoWiFiSettingEnabled(isEnabled));
268         overrideCarrierConfig(null);
269     }
270 
271     /**
272      * Set the VoWiFi roaming setting and ensure it is queried successfully. Also ensure the
273      * ContentObserver is triggered properly.
274      */
275     @Test
testVoWiFiRoamingSetting()276     public void testVoWiFiRoamingSetting() throws Exception {
277         if (!ImsUtils.shouldTestImsService()) {
278             return;
279         }
280 
281         Uri callingUri = Uri.withAppendedPath(
282                 SubscriptionManager.WFC_ROAMING_ENABLED_CONTENT_URI, "" + sTestSub);
283         CountDownLatch contentObservedLatch = new CountDownLatch(1);
284         ContentObserver observer = createObserver(callingUri, contentObservedLatch);
285 
286         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
287         ImsMmTelManager mMmTelManager = imsManager.getImsMmTelManager(sTestSub);
288         boolean isEnabled = ShellIdentityUtils.invokeMethodWithShellPermissions(mMmTelManager,
289                 ImsMmTelManager::isVoWiFiRoamingSettingEnabled);
290         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mMmTelManager,
291                 (m) -> m.setVoWiFiRoamingSettingEnabled(!isEnabled));
292 
293         waitForLatch(contentObservedLatch, observer);
294         boolean isEnabledResult = ShellIdentityUtils.invokeMethodWithShellPermissions(mMmTelManager,
295                 ImsMmTelManager::isVoWiFiRoamingSettingEnabled);
296         assertEquals("isVoWiFiRoamingSettingEnabled result does not match the value set by "
297                 + "setVoWiFiRoamingSettingEnabled", !isEnabled, isEnabledResult);
298 
299         // Set back to default
300         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mMmTelManager,
301                 (m) -> m.setVoWiFiRoamingSettingEnabled(isEnabled));
302     }
303 
304     /**
305      * Expect to fail when Set the VoWiFi Mode setting withour proper permission
306      */
307     @Test
testGetVoWiFiModeSetting_noPermission()308     public void testGetVoWiFiModeSetting_noPermission() throws Exception {
309         if (!ImsUtils.shouldTestImsService()) {
310             return;
311         }
312         try {
313             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
314             ImsMmTelManager mMmTelManager = imsManager.getImsMmTelManager(sTestSub);
315             int oldMode = mMmTelManager.getVoWiFiModeSetting();
316             fail("Expected SecurityException for missing permissoins");
317         } catch (SecurityException ex) {
318             /* Expected */
319         }
320 
321     }
322 
323     /**
324      * Expect to fail when Set the VoWiFi Mode setting withour proper permission
325      */
326     @Test
testGetVoWiFiRoamingModeSetting_noPermission()327     public void testGetVoWiFiRoamingModeSetting_noPermission() throws Exception {
328         if (!ImsUtils.shouldTestImsService()) {
329             return;
330         }
331         try {
332             ImsManager imsManager = getContext().getSystemService(ImsManager.class);
333             ImsMmTelManager mMmTelManager = imsManager.getImsMmTelManager(sTestSub);
334             int oldMode = mMmTelManager.getVoWiFiRoamingModeSetting();
335             fail("Expected SecurityException for missing permissoins");
336         } catch (SecurityException ex) {
337             /* Expected */
338         }
339 
340     }
341 
342 
343     /**
344      * Set the VoWiFi Mode setting and ensure the ContentResolver is triggered as well.
345      */
346     @Test
testVoWiFiModeSetting()347     public void testVoWiFiModeSetting() throws Exception {
348         if (!ImsUtils.shouldTestImsService()) {
349             return;
350         }
351 
352         PersistableBundle bundle = new PersistableBundle();
353         bundle.putBoolean(KEY_EDITABLE_WFC_MODE_BOOL, true);
354         overrideCarrierConfig(bundle);
355         // Register Observer
356         Uri callingUri = Uri.withAppendedPath(
357                 SubscriptionManager.WFC_MODE_CONTENT_URI, "" + sTestSub);
358         CountDownLatch contentObservedLatch = new CountDownLatch(1);
359         ContentObserver observer = createObserver(callingUri, contentObservedLatch);
360 
361         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
362         ImsMmTelManager mMmTelManager = imsManager.getImsMmTelManager(sTestSub);
363         int oldMode = ShellIdentityUtils.invokeMethodWithShellPermissions(mMmTelManager,
364                 ImsMmTelManager::getVoWiFiModeSetting);
365         // Keep the mode in the bounds 0-2
366         int newMode = (oldMode + 1) % 3;
367         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mMmTelManager,
368                 (m) -> m.setVoWiFiModeSetting(newMode));
369 
370         waitForLatch(contentObservedLatch, observer);
371         int newModeResult = ShellIdentityUtils.invokeMethodWithShellPermissions(mMmTelManager,
372                 ImsMmTelManager::getVoWiFiModeSetting);
373         assertEquals(newMode, newModeResult);
374 
375         // Set back to default
376         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mMmTelManager,
377                 (m) -> m.setVoWiFiModeSetting(oldMode));
378         overrideCarrierConfig(null);
379     }
380 
381     /**
382      * Set the VoWiFi Mode setting and ensure the ContentResolver is triggered as well.
383      */
384     @Test
testVoWiFiRoamingModeSetting()385     public void testVoWiFiRoamingModeSetting() throws Exception {
386         if (!ImsUtils.shouldTestImsService()) {
387             return;
388         }
389 
390         PersistableBundle bundle = new PersistableBundle();
391         // Ensure the WFC roaming mode will be changed properly
392         bundle.putBoolean(KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL, false);
393         bundle.putBoolean(KEY_EDITABLE_WFC_ROAMING_MODE_BOOL, true);
394         overrideCarrierConfig(bundle);
395         // Register Observer
396         Uri callingUri = Uri.withAppendedPath(
397                 SubscriptionManager.WFC_ROAMING_MODE_CONTENT_URI, "" + sTestSub);
398         CountDownLatch contentObservedLatch = new CountDownLatch(1);
399         ContentObserver observer = createObserver(callingUri, contentObservedLatch);
400 
401         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
402         ImsMmTelManager mMmTelManager = imsManager.getImsMmTelManager(sTestSub);
403         int oldMode = ShellIdentityUtils.invokeMethodWithShellPermissions(mMmTelManager,
404                 ImsMmTelManager::getVoWiFiRoamingModeSetting);
405         // Keep the mode in the bounds 0-2
406         int newMode = (oldMode + 1) % 3;
407         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mMmTelManager,
408                 (m) -> m.setVoWiFiRoamingModeSetting(newMode));
409 
410         waitForLatch(contentObservedLatch, observer);
411         int newModeResult = ShellIdentityUtils.invokeMethodWithShellPermissions(mMmTelManager,
412                 ImsMmTelManager::getVoWiFiRoamingModeSetting);
413         assertEquals("getVoWiFiRoamingModeSetting was not set to value set by"
414                 + "setVoWiFiRoamingModeSetting", newMode, newModeResult);
415 
416         // Set back to default
417         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mMmTelManager,
418                 (m) -> m.setVoWiFiRoamingModeSetting(oldMode));
419         overrideCarrierConfig(null);
420     }
421 
422     /**
423      * Test Permissions on various APIs.
424      */
425     @Test
testMethodPermissions()426     public void testMethodPermissions() throws Exception {
427         if (!ImsUtils.shouldTestImsService()) {
428             return;
429         }
430 
431         ImsManager imsManager = getContext().getSystemService(ImsManager.class);
432         ImsMmTelManager mMmTelManager = imsManager.getImsMmTelManager(sTestSub);
433         // setRttCapabilitySetting
434         try {
435             mMmTelManager.setRttCapabilitySetting(false);
436             fail("setRttCapabilitySetting requires MODIFY_PHONE_STATE permission.");
437         } catch (SecurityException e) {
438             //expected
439         }
440         try {
441             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mMmTelManager,
442                     (m) -> m.setRttCapabilitySetting(false),
443                     "android.permission.MODIFY_PHONE_STATE");
444         } catch (SecurityException e) {
445             fail("setRttCapabilitySetting requires MODIFY_PHONE_STATE permission.");
446         }
447         // setVoWiFiNonPersistent
448         try {
449             mMmTelManager.setVoWiFiNonPersistent(true,
450                     ImsMmTelManager.WIFI_MODE_CELLULAR_PREFERRED);
451             fail("setVoWiFiNonPersistent requires MODIFY_PHONE_STATE permission.");
452         } catch (SecurityException e) {
453             //expected
454         }
455         try {
456             ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mMmTelManager,
457                     (m) -> m.setVoWiFiNonPersistent(true,
458                             ImsMmTelManager.WIFI_MODE_CELLULAR_PREFERRED),
459                     "android.permission.MODIFY_PHONE_STATE");
460         } catch (SecurityException e) {
461             fail("setVoWiFiNonPersistent requires MODIFY_PHONE_STATE permission.");
462         }
463 
464         try {
465             mMmTelManager.isVtSettingEnabled();
466             fail("isVtSettingEnabled requires READ_PRECISE_PHONE_STATE permission.");
467         } catch (SecurityException e) {
468             //expected
469         }
470 
471         try {
472             mMmTelManager.isAdvancedCallingSettingEnabled();
473             fail("isAdvancedCallingSettingEnabled requires READ_PRECISE_PHONE_STATE.");
474         } catch (SecurityException e) {
475             //expected
476         }
477 
478         try {
479             mMmTelManager.isVoWiFiRoamingSettingEnabled();
480             fail("isVoWiFiRoamingSettingEnabled requires READ_PRECISE_PHONE_STATE permission.");
481         } catch (SecurityException e) {
482             //expected
483         }
484 
485         try {
486             mMmTelManager.isVoWiFiSettingEnabled();
487             fail("isVoWiFiSettingEnabled requires READ_PRECISE_PHONE_STATE permission.");
488         } catch (SecurityException e) {
489             //expected
490         }
491 
492         try {
493             mMmTelManager.isTtyOverVolteEnabled();
494             fail("isTtyOverVolteEnabled requires READ_PRIVILEGED_PHONE_STATE permission.");
495         } catch (SecurityException e) {
496             //expected
497         }
498         try {
499             mMmTelManager.isSupported(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
500                     AccessNetworkConstants.TRANSPORT_TYPE_WWAN, Runnable::run, (result) -> { });
501             fail("isSupported requires READ_PRIVILEGED_PHONE_STATE permission.");
502         } catch (SecurityException e) {
503             //expected
504         }
505         try {
506             mMmTelManager.getRegistrationState(Runnable::run, (result) -> { });
507             fail("getRegistrationState requires READ_PRECISE_PHONE_STATE permission.");
508         } catch (SecurityException e) {
509             //expected
510         }
511         try {
512             mMmTelManager.getRegistrationTransportType(Runnable::run, (result) -> { });
513             fail("getRegistrationTransportType requires READ_PRIVILEGED_PHONE_STATE permission.");
514         } catch (SecurityException e) {
515             //expected
516         }
517 
518         try {
519             mMmTelManager.isSupported(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
520                     AccessNetworkConstants.TRANSPORT_TYPE_WWAN, Runnable::run, (result) -> { });
521             fail("isSupported requires READ_PRIVILEGED_PHONE_STATE permission.");
522         } catch (SecurityException e) {
523             //expected
524         }
525 
526         try {
527             ShellIdentityUtils.invokeMethodWithShellPermissions(mMmTelManager,
528                     ImsMmTelManager::isTtyOverVolteEnabled,
529                     "android.permission.READ_PRIVILEGED_PHONE_STATE");
530         } catch (SecurityException e) {
531             fail("isTtyOverVolteEnabled requires READ_PRIVILEGED_PHONE_STATE permission.");
532         }
533         try {
534             LinkedBlockingQueue<Boolean> resultQueue = new LinkedBlockingQueue<>(1);
535             ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(mMmTelManager,
536                     (m) -> m.isSupported(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
537                             AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
538                             // Run on the binder thread.
539                             Runnable::run,
540                             resultQueue::offer), ImsException.class,
541                     "android.permission.READ_PRIVILEGED_PHONE_STATE");
542             assertNotNull(resultQueue.poll(ImsUtils.TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS));
543         } catch (SecurityException e) {
544             fail("isSupported requires READ_PRIVILEGED_PHONE_STATE permission.");
545         }
546         try {
547             LinkedBlockingQueue<Integer> resultQueue = new LinkedBlockingQueue<>(1);
548             ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(mMmTelManager,
549                     (m) -> m.getRegistrationState(Runnable::run, resultQueue::offer),
550                     ImsException.class, "android.permission.READ_PRIVILEGED_PHONE_STATE");
551             assertNotNull(resultQueue.poll(ImsUtils.TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS));
552         } catch (SecurityException e) {
553             fail("getRegistrationState requires READ_PRIVILEGED_PHONE_STATE permission.");
554         }
555         try {
556             LinkedBlockingQueue<Integer> resultQueue = new LinkedBlockingQueue<>(1);
557             ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(mMmTelManager,
558                     (m) -> m.getRegistrationTransportType(Runnable::run, resultQueue::offer),
559                     ImsException.class, "android.permission.READ_PRIVILEGED_PHONE_STATE");
560             assertNotNull(resultQueue.poll(ImsUtils.TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS));
561         } catch (SecurityException e) {
562             fail("getRegistrationTransportType requires READ_PRIVILEGED_PHONE_STATE permission.");
563         }
564     }
565 
overrideCarrierConfig(PersistableBundle bundle)566     private void overrideCarrierConfig(PersistableBundle bundle) throws Exception {
567         CarrierConfigManager carrierConfigManager = getContext().getSystemService(
568                 CarrierConfigManager.class);
569         sReceiver.clearQueue();
570         ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(carrierConfigManager,
571                 (m) -> m.overrideConfig(sTestSub, bundle));
572         sReceiver.waitForCarrierConfigChanged();
573     }
574 
createObserver(Uri observerUri, CountDownLatch latch)575     private ContentObserver createObserver(Uri observerUri, CountDownLatch latch) {
576         ContentObserver observer = new ContentObserver(sHandler) {
577             @Override
578             public void onChange(boolean selfChange, Uri uri) {
579                 if (observerUri.equals(uri)) {
580                     latch.countDown();
581                 }
582             }
583         };
584         getContext().getContentResolver().registerContentObserver(observerUri, true, observer);
585         return observer;
586     }
587 
waitForLatch(CountDownLatch latch, ContentObserver observer)588     private void waitForLatch(CountDownLatch latch, ContentObserver observer) {
589         try {
590             // Wait for the ContentObserver to fire signalling the change.
591             latch.await(ImsUtils.TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
592         } catch (InterruptedException e) {
593             fail("Interrupted Exception waiting for latch countdown:" + e.getMessage());
594         } finally {
595             getContext().getContentResolver().unregisterContentObserver(observer);
596         }
597     }
598 
getContext()599     private static Context getContext() {
600         return InstrumentationRegistry.getInstrumentation().getContext();
601     }
602 }
603