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