• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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.phone;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertThrows;
22 import static org.junit.Assert.assertTrue;
23 import static org.junit.Assert.fail;
24 import static org.mockito.ArgumentMatchers.anyInt;
25 import static org.mockito.ArgumentMatchers.anyString;
26 import static org.mockito.ArgumentMatchers.eq;
27 import static org.mockito.ArgumentMatchers.isNull;
28 import static org.mockito.Mockito.doNothing;
29 import static org.mockito.Mockito.doReturn;
30 import static org.mockito.Mockito.doThrow;
31 import static org.mockito.Mockito.mock;
32 import static org.mockito.Mockito.never;
33 import static org.mockito.Mockito.spy;
34 import static org.mockito.Mockito.verify;
35 import static org.mockito.Mockito.when;
36 
37 import android.app.AppOpsManager;
38 import android.compat.testing.PlatformCompatChangeRule;
39 import android.content.Context;
40 import android.content.SharedPreferences;
41 import android.content.pm.PackageManager;
42 import android.content.res.Resources;
43 import android.os.Build;
44 import android.permission.flags.Flags;
45 import android.platform.test.flag.junit.SetFlagsRule;
46 import android.telephony.RadioAccessFamily;
47 import android.telephony.TelephonyManager;
48 
49 import androidx.test.annotation.UiThreadTest;
50 import androidx.test.ext.junit.runners.AndroidJUnit4;
51 
52 import com.android.TelephonyTestBase;
53 import com.android.internal.telephony.IIntegerConsumer;
54 import com.android.internal.telephony.Phone;
55 import com.android.internal.telephony.RILConstants;
56 import com.android.internal.telephony.flags.FeatureFlags;
57 import com.android.internal.telephony.subscription.SubscriptionManagerService;
58 
59 import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
60 
61 import org.junit.Before;
62 import org.junit.Rule;
63 import org.junit.Test;
64 import org.junit.rules.TestRule;
65 import org.junit.runner.RunWith;
66 import org.mockito.Mock;
67 
68 import java.lang.reflect.Field;
69 import java.lang.reflect.Modifier;
70 import java.util.Collections;
71 import java.util.Locale;
72 
73 /**
74  * Unit Test for PhoneInterfaceManager.
75  */
76 @RunWith(AndroidJUnit4.class)
77 public class PhoneInterfaceManagerTest extends TelephonyTestBase {
78     @Rule
79     public TestRule compatChangeRule = new PlatformCompatChangeRule();
80 
81     private PhoneInterfaceManager mPhoneInterfaceManager;
82     private SharedPreferences mSharedPreferences;
83     private IIntegerConsumer mIIntegerConsumer;
84     private static final String sDebugPackageName =
85             PhoneInterfaceManagerTest.class.getPackageName();
86 
87     @Mock
88     PhoneGlobals mPhoneGlobals;
89     @Mock
90     Phone mPhone;
91     @Mock
92     FeatureFlags mFeatureFlags;
93     @Mock
94     PackageManager mPackageManager;
95     @Mock
96     private SubscriptionManagerService mSubscriptionManagerService;
97 
98     @Mock
99     private AppOpsManager mAppOps;
100 
101     @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
102 
103     @Before
104     @UiThreadTest
setUp()105     public void setUp() throws Exception {
106         super.setUp();
107         doReturn(sDebugPackageName).when(mPhoneGlobals).getOpPackageName();
108 
109         // Note that PhoneInterfaceManager is a singleton. Calling init gives us a handle to the
110         // global singleton, but the context that is passed in is unused if the phone app is already
111         // alive on a test devices. You must use the spy to mock behavior. Mocks stemming from the
112         // passed context will remain unused.
113         mPhoneInterfaceManager = spy(PhoneInterfaceManager.init(mPhoneGlobals, mFeatureFlags));
114         doReturn(mSubscriptionManagerService).when(mPhoneInterfaceManager)
115                 .getSubscriptionManagerService();
116         TelephonyManager.setupISubForTest(mSubscriptionManagerService);
117         mSharedPreferences = mPhoneInterfaceManager.getSharedPreferences();
118         mSharedPreferences.edit().remove(Phone.PREF_NULL_CIPHER_AND_INTEGRITY_ENABLED).commit();
119         mSharedPreferences.edit().remove(Phone.PREF_NULL_CIPHER_NOTIFICATIONS_ENABLED).commit();
120         mIIntegerConsumer = mock(IIntegerConsumer.class);
121 
122         // In order not to affect the existing implementation, define a telephony features
123         // and disabled enforce_telephony_feature_mapping_for_public_apis feature flag
124         mPhoneInterfaceManager.setFeatureFlags(mFeatureFlags);
125         doReturn(false).when(mFeatureFlags).enforceTelephonyFeatureMappingForPublicApis();
126         mPhoneInterfaceManager.setPackageManager(mPackageManager);
127         doReturn(true).when(mPackageManager).hasSystemFeature(anyString());
128 
129         mPhoneInterfaceManager.setAppOpsManager(mAppOps);
130     }
131 
132     @Test
cleanUpAllowedNetworkTypes_validPhoneAndSubId_doSetAllowedNetwork()133     public void cleanUpAllowedNetworkTypes_validPhoneAndSubId_doSetAllowedNetwork() {
134         long defaultNetworkType = RadioAccessFamily.getRafFromNetworkType(
135                 RILConstants.PREFERRED_NETWORK_MODE);
136 
137         mPhoneInterfaceManager.cleanUpAllowedNetworkTypes(mPhone, 1);
138 
139         verify(mPhone).loadAllowedNetworksFromSubscriptionDatabase();
140         verify(mPhone).setAllowedNetworkTypes(TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER,
141                 defaultNetworkType, null);
142     }
143 
144     @Test
cleanUpAllowedNetworkTypes_validPhoneAndInvalidSubId_doNotSetAllowedNetwork()145     public void cleanUpAllowedNetworkTypes_validPhoneAndInvalidSubId_doNotSetAllowedNetwork() {
146         long defaultNetworkType = RadioAccessFamily.getRafFromNetworkType(
147                 RILConstants.PREFERRED_NETWORK_MODE);
148 
149         mPhoneInterfaceManager.cleanUpAllowedNetworkTypes(mPhone, -1);
150 
151         verify(mPhone, never()).loadAllowedNetworksFromSubscriptionDatabase();
152         verify(mPhone, never()).setAllowedNetworkTypes(
153                 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, defaultNetworkType, null);
154     }
155 
156     @Test
matchLocaleFromSupportedLocaleList_inputLocaleChangeToSupportedLocale_notMatched()157     public void matchLocaleFromSupportedLocaleList_inputLocaleChangeToSupportedLocale_notMatched() {
158         Context context = mock(Context.class);
159         when(mPhone.getContext()).thenReturn(context);
160         Resources resources = mock(Resources.class);
161         when(context.getResources()).thenReturn(resources);
162         when(resources.getStringArray(anyInt()))
163                 .thenReturn(new String[]{"fi-FI", "ff-Adlm-BF", "en-US"});
164 
165         // Input empty string, then return default locale of ICU.
166         String resultInputEmpty = mPhoneInterfaceManager.matchLocaleFromSupportedLocaleList(mPhone,
167                 Locale.forLanguageTag(""));
168 
169         assertEquals("und", resultInputEmpty);
170 
171         // Input en, then look up the matched supported locale. No matched, so return input locale.
172         String resultOnlyLanguage = mPhoneInterfaceManager.matchLocaleFromSupportedLocaleList(
173                 mPhone,
174                 Locale.forLanguageTag("en"));
175 
176         assertEquals("en", resultOnlyLanguage);
177     }
178 
179     @Test
matchLocaleFromSupportedLocaleList_inputLocaleChangeToSupportedLocale()180     public void matchLocaleFromSupportedLocaleList_inputLocaleChangeToSupportedLocale() {
181         Context context = mock(Context.class);
182         when(mPhone.getContext()).thenReturn(context);
183         Resources resources = mock(Resources.class);
184         when(context.getResources()).thenReturn(resources);
185         when(resources.getStringArray(anyInt())).thenReturn(new String[]{"zh-Hant-TW"});
186 
187         // Input zh-TW, then look up the matched supported locale, zh-Hant-TW, instead.
188         String resultInputZhTw = mPhoneInterfaceManager.matchLocaleFromSupportedLocaleList(mPhone,
189                 Locale.forLanguageTag("zh-TW"));
190 
191         assertEquals("zh-Hant-TW", resultInputZhTw);
192 
193         when(resources.getStringArray(anyInt())).thenReturn(
194                 new String[]{"fi-FI", "ff-Adlm-BF", "ff-Latn-BF"});
195 
196         // Input ff-BF, then find the matched supported locale, ff-Latn-BF, instead.
197         String resultFfBf = mPhoneInterfaceManager.matchLocaleFromSupportedLocaleList(mPhone,
198                 Locale.forLanguageTag("ff-BF"));
199 
200         assertEquals("ff-Latn-BF", resultFfBf);
201     }
202 
203     @Test
setNullCipherAndIntegrityEnabled_successfullyEnable()204     public void setNullCipherAndIntegrityEnabled_successfullyEnable() {
205         whenModemSupportsNullCiphers();
206         doReturn(201).when(mPhoneInterfaceManager).getHalVersion(anyInt());
207         doNothing().when(mPhoneInterfaceManager).enforceModifyPermission();
208         assertFalse(mSharedPreferences.contains(Phone.PREF_NULL_CIPHER_AND_INTEGRITY_ENABLED));
209 
210         mPhoneInterfaceManager.setNullCipherAndIntegrityEnabled(true);
211 
212         assertTrue(
213                 mSharedPreferences.getBoolean(Phone.PREF_NULL_CIPHER_AND_INTEGRITY_ENABLED, false));
214     }
215 
216     @Test
setNullCipherAndIntegrityEnabled_successfullyDisable()217     public void setNullCipherAndIntegrityEnabled_successfullyDisable() {
218         whenModemSupportsNullCiphers();
219         doReturn(201).when(mPhoneInterfaceManager).getHalVersion(anyInt());
220         doNothing().when(mPhoneInterfaceManager).enforceModifyPermission();
221         assertFalse(mSharedPreferences.contains(Phone.PREF_NULL_CIPHER_AND_INTEGRITY_ENABLED));
222 
223         mPhoneInterfaceManager.setNullCipherAndIntegrityEnabled(false);
224 
225         assertFalse(
226                 mSharedPreferences.getBoolean(Phone.PREF_NULL_CIPHER_AND_INTEGRITY_ENABLED, true));
227     }
228 
229     @Test
setNullCipherAndIntegrityEnabled_lackingNecessaryHal()230     public void setNullCipherAndIntegrityEnabled_lackingNecessaryHal() {
231         doReturn(101).when(mPhoneInterfaceManager).getHalVersion(anyInt());
232         doNothing().when(mPhoneInterfaceManager).enforceModifyPermission();
233 
234         assertThrows(UnsupportedOperationException.class, () -> {
235             mPhoneInterfaceManager.setNullCipherAndIntegrityEnabled(true);
236         });
237 
238     }
239 
240     @Test
setNullCipherAndIntegrityEnabled_lackingPermissions()241     public void setNullCipherAndIntegrityEnabled_lackingPermissions() {
242         doReturn(201).when(mPhoneInterfaceManager).getHalVersion(anyInt());
243         doThrow(SecurityException.class).when(mPhoneInterfaceManager).enforceModifyPermission();
244 
245         assertThrows(SecurityException.class, () -> {
246             mPhoneInterfaceManager.setNullCipherAndIntegrityEnabled(true);
247         });
248     }
249 
250     @Test
isNullCipherAndIntegrityPreferenceEnabled()251     public void isNullCipherAndIntegrityPreferenceEnabled() {
252         whenModemSupportsNullCiphers();
253         doReturn(201).when(mPhoneInterfaceManager).getHalVersion(anyInt());
254         doNothing().when(mPhoneInterfaceManager).enforceModifyPermission();
255 
256         mPhoneInterfaceManager.setNullCipherAndIntegrityEnabled(false);
257         assertFalse(
258                 mSharedPreferences.getBoolean(Phone.PREF_NULL_CIPHER_AND_INTEGRITY_ENABLED, true));
259     }
260 
261     @Test
isNullCipherAndIntegrityPreferenceEnabled_lackingNecessaryHal()262     public void isNullCipherAndIntegrityPreferenceEnabled_lackingNecessaryHal() {
263         doReturn(101).when(mPhoneInterfaceManager).getHalVersion(anyInt());
264         doNothing().when(mPhoneInterfaceManager).enforceModifyPermission();
265 
266         assertThrows(UnsupportedOperationException.class, () -> {
267             mPhoneInterfaceManager.isNullCipherAndIntegrityPreferenceEnabled();
268         });
269 
270     }
271 
272     @Test
isNullCipherAndIntegrityPreferenceEnabled_lackingModemSupport()273     public void isNullCipherAndIntegrityPreferenceEnabled_lackingModemSupport() {
274         whenModemDoesNotSupportNullCiphers();
275         doReturn(201).when(mPhoneInterfaceManager).getHalVersion(anyInt());
276         doNothing().when(mPhoneInterfaceManager).enforceModifyPermission();
277 
278         assertThrows(UnsupportedOperationException.class, () -> {
279             mPhoneInterfaceManager.isNullCipherAndIntegrityPreferenceEnabled();
280         });
281 
282     }
283 
284     @Test
isNullCipherAndIntegrityPreferenceEnabled_lackingPermissions()285     public void isNullCipherAndIntegrityPreferenceEnabled_lackingPermissions() {
286         doReturn(201).when(mPhoneInterfaceManager).getHalVersion(anyInt());
287         doThrow(SecurityException.class).when(mPhoneInterfaceManager).enforceReadPermission();
288 
289         assertThrows(SecurityException.class, () -> {
290             mPhoneInterfaceManager.isNullCipherAndIntegrityPreferenceEnabled();
291         });
292     }
293 
whenModemDoesNotSupportNullCiphers()294     private void whenModemDoesNotSupportNullCiphers() {
295         doReturn(false).when(mPhone).isNullCipherAndIntegritySupported();
296         doReturn(mPhone).when(
297                 mPhoneInterfaceManager).getDefaultPhone();
298     }
299 
whenModemSupportsNullCiphers()300     private void whenModemSupportsNullCiphers() {
301         doReturn(true).when(mPhone).isNullCipherAndIntegritySupported();
302         doReturn(mPhone).when(
303                 mPhoneInterfaceManager).getDefaultPhone();
304     }
305 
306     @Test
setNullCipherNotificationsEnabled_allReqsMet_successfullyEnabled()307     public void setNullCipherNotificationsEnabled_allReqsMet_successfullyEnabled() {
308         setModemSupportsNullCipherNotification(true);
309         doNothing().when(mPhoneInterfaceManager).enforceModifyPermission();
310         doReturn(202).when(mPhoneInterfaceManager).getHalVersion(anyInt());
311         assertFalse(mSharedPreferences.contains(Phone.PREF_NULL_CIPHER_NOTIFICATIONS_ENABLED));
312 
313         mPhoneInterfaceManager.setNullCipherNotificationsEnabled(true);
314 
315         assertTrue(
316                 mSharedPreferences.getBoolean(Phone.PREF_NULL_CIPHER_NOTIFICATIONS_ENABLED, false));
317     }
318 
319     @Test
setNullCipherNotificationsEnabled_allReqsMet_successfullyDisabled()320     public void setNullCipherNotificationsEnabled_allReqsMet_successfullyDisabled() {
321         setModemSupportsNullCipherNotification(true);
322         doNothing().when(mPhoneInterfaceManager).enforceModifyPermission();
323         doReturn(202).when(mPhoneInterfaceManager).getHalVersion(anyInt());
324         assertFalse(mSharedPreferences.contains(Phone.PREF_NULL_CIPHER_NOTIFICATIONS_ENABLED));
325 
326         mPhoneInterfaceManager.setNullCipherNotificationsEnabled(false);
327 
328         assertFalse(
329                 mSharedPreferences.getBoolean(Phone.PREF_NULL_CIPHER_NOTIFICATIONS_ENABLED, true));
330     }
331 
332     @Test
setNullCipherNotificationsEnabled_lackingNecessaryHal_throwsException()333     public void setNullCipherNotificationsEnabled_lackingNecessaryHal_throwsException() {
334         setModemSupportsNullCipherNotification(true);
335         doNothing().when(mPhoneInterfaceManager).enforceModifyPermission();
336         doReturn(102).when(mPhoneInterfaceManager).getHalVersion(anyInt());
337 
338         assertThrows(UnsupportedOperationException.class,
339                 () -> mPhoneInterfaceManager.setNullCipherNotificationsEnabled(true));
340     }
341 
342     @Test
setNullCipherNotificationsEnabled_lackingModemSupport_throwsException()343     public void setNullCipherNotificationsEnabled_lackingModemSupport_throwsException() {
344         setModemSupportsNullCipherNotification(false);
345         doNothing().when(mPhoneInterfaceManager).enforceModifyPermission();
346         doReturn(202).when(mPhoneInterfaceManager).getHalVersion(anyInt());
347 
348         assertThrows(UnsupportedOperationException.class,
349                 () -> mPhoneInterfaceManager.setNullCipherNotificationsEnabled(true));
350     }
351 
352     @Test
setNullCipherNotificationsEnabled_lackingPermissions_throwsException()353     public void setNullCipherNotificationsEnabled_lackingPermissions_throwsException() {
354         setModemSupportsNullCipherNotification(true);
355         doReturn(202).when(mPhoneInterfaceManager).getHalVersion(anyInt());
356         doThrow(SecurityException.class).when(mPhoneInterfaceManager).enforceModifyPermission();
357 
358         assertThrows(SecurityException.class, () ->
359                 mPhoneInterfaceManager.setNullCipherNotificationsEnabled(true));
360     }
361 
362     @Test
isNullCipherNotificationsEnabled_allReqsMet_returnsTrue()363     public void isNullCipherNotificationsEnabled_allReqsMet_returnsTrue() {
364         setModemSupportsNullCipherNotification(true);
365         doReturn(202).when(mPhoneInterfaceManager).getHalVersion(anyInt());
366         doNothing().when(mPhoneInterfaceManager).enforceReadPrivilegedPermission(anyString());
367         doReturn(true).when(mPhone).getNullCipherNotificationsPreferenceEnabled();
368 
369         assertTrue(mPhoneInterfaceManager.isNullCipherNotificationsEnabled());
370     }
371 
372     @Test
isNullCipherNotificationsEnabled_lackingNecessaryHal_throwsException()373     public void isNullCipherNotificationsEnabled_lackingNecessaryHal_throwsException() {
374         setModemSupportsNullCipherNotification(true);
375         doReturn(102).when(mPhoneInterfaceManager).getHalVersion(anyInt());
376         doNothing().when(mPhoneInterfaceManager).enforceReadPrivilegedPermission(anyString());
377 
378         assertThrows(UnsupportedOperationException.class, () ->
379                 mPhoneInterfaceManager.isNullCipherNotificationsEnabled());
380     }
381 
382     @Test
isNullCipherNotificationsEnabled_lackingModemSupport_throwsException()383     public void isNullCipherNotificationsEnabled_lackingModemSupport_throwsException() {
384         setModemSupportsNullCipherNotification(false);
385         doReturn(202).when(mPhoneInterfaceManager).getHalVersion(anyInt());
386         doNothing().when(mPhoneInterfaceManager).enforceReadPrivilegedPermission(anyString());
387 
388         assertThrows(UnsupportedOperationException.class, () ->
389                 mPhoneInterfaceManager.isNullCipherNotificationsEnabled());
390     }
391 
392     @Test
isNullCipherNotificationsEnabled_lackingPermissions_throwsException()393     public void isNullCipherNotificationsEnabled_lackingPermissions_throwsException() {
394         setModemSupportsNullCipherNotification(true);
395         doReturn(202).when(mPhoneInterfaceManager).getHalVersion(anyInt());
396         doThrow(SecurityException.class).when(
397                 mPhoneInterfaceManager).enforceReadPrivilegedPermission(anyString());
398 
399         assertThrows(SecurityException.class, () ->
400                 mPhoneInterfaceManager.isNullCipherNotificationsEnabled());
401     }
402 
setModemSupportsNullCipherNotification(boolean enable)403     private void setModemSupportsNullCipherNotification(boolean enable) {
404         doReturn(enable).when(mPhone).isNullCipherNotificationSupported();
405         doReturn(mPhone).when(mPhoneInterfaceManager).getDefaultPhone();
406     }
407 
408     /**
409      * Verify getCarrierRestrictionStatus throws exception for invalid caller package name.
410      */
411     @Test
getCarrierRestrictionStatus_ReadPrivilegedException2()412     public void getCarrierRestrictionStatus_ReadPrivilegedException2() {
413         doThrow(SecurityException.class).when(
414                 mPhoneInterfaceManager).enforceReadPrivilegedPermission(anyString());
415         assertThrows(SecurityException.class, () -> {
416             mPhoneInterfaceManager.getCarrierRestrictionStatus(mIIntegerConsumer, "");
417         });
418     }
419 
420     /**
421      * Verify getCarrierRestrictionStatus doesn't throw any exception with valid package name
422      * and with READ_PHONE_STATE permission granted.
423      */
424     @Test
getCarrierRestrictionStatus()425     public void getCarrierRestrictionStatus() {
426         when(mPhoneInterfaceManager.validateCallerAndGetCarrierIds(anyString())).thenReturn(
427                 Collections.singleton(1));
428         mPhoneInterfaceManager.getCarrierRestrictionStatus(mIIntegerConsumer,
429                 "com.test.package");
430     }
431 
432     @Test
notifyEnableDataWithAppOps_enableByUser_doNoteOp()433     public void notifyEnableDataWithAppOps_enableByUser_doNoteOp() {
434         mSetFlagsRule.enableFlags(Flags.FLAG_OP_ENABLE_MOBILE_DATA_BY_USER);
435         String packageName = "INVALID_PACKAGE";
436         mPhoneInterfaceManager.setDataEnabledForReason(1,
437                 TelephonyManager.DATA_ENABLED_REASON_USER, true, packageName);
438         verify(mAppOps).noteOpNoThrow(eq(AppOpsManager.OPSTR_ENABLE_MOBILE_DATA_BY_USER), anyInt(),
439                 eq(packageName), isNull(), isNull());
440     }
441 
442     @Test
notifyEnableDataWithAppOps_enableByCarrier_doNotNoteOp()443     public void notifyEnableDataWithAppOps_enableByCarrier_doNotNoteOp() {
444         mSetFlagsRule.enableFlags(Flags.FLAG_OP_ENABLE_MOBILE_DATA_BY_USER);
445         String packageName = "INVALID_PACKAGE";
446         verify(mAppOps, never()).noteOpNoThrow(eq(AppOpsManager.OPSTR_ENABLE_MOBILE_DATA_BY_USER),
447                 anyInt(), eq(packageName), isNull(), isNull());
448     }
449 
450     @Test
notifyEnableDataWithAppOps_disableByUser_doNotNoteOp()451     public void notifyEnableDataWithAppOps_disableByUser_doNotNoteOp() {
452         mSetFlagsRule.enableFlags(Flags.FLAG_OP_ENABLE_MOBILE_DATA_BY_USER);
453         String packageName = "INVALID_PACKAGE";
454         String error = "";
455         try {
456             mPhoneInterfaceManager.setDataEnabledForReason(1,
457                     TelephonyManager.DATA_ENABLED_REASON_USER, false, packageName);
458         } catch (SecurityException expected) {
459             // The test doesn't have access to note the op, but we're just interested that it makes
460             // the attempt.
461             error = expected.getMessage();
462         }
463         assertEquals("Expected error to be empty, was " + error, error, "");
464     }
465 
466     @Test
notifyEnableDataWithAppOps_noPackageNameAndEnableByUser_doNotnoteOp()467     public void notifyEnableDataWithAppOps_noPackageNameAndEnableByUser_doNotnoteOp() {
468         mSetFlagsRule.enableFlags(Flags.FLAG_OP_ENABLE_MOBILE_DATA_BY_USER);
469         String error = "";
470         try {
471             mPhoneInterfaceManager.setDataEnabledForReason(1,
472                     TelephonyManager.DATA_ENABLED_REASON_USER, false, null);
473         } catch (SecurityException expected) {
474             // The test doesn't have access to note the op, but we're just interested that it makes
475             // the attempt.
476             error = expected.getMessage();
477         }
478         assertEquals("Expected error to be empty, was " + error, error, "");
479     }
480 
481     @Test
482     @EnableCompatChanges({TelephonyManager.ENABLE_FEATURE_MAPPING})
testWithTelephonyFeatureAndCompatChanges()483     public void testWithTelephonyFeatureAndCompatChanges() throws Exception {
484         doReturn(true).when(mFeatureFlags).enforceTelephonyFeatureMappingForPublicApis();
485         mPhoneInterfaceManager.setFeatureFlags(mFeatureFlags);
486         doNothing().when(mPhoneInterfaceManager).enforceModifyPermission();
487 
488         try {
489             // FEATURE_TELEPHONY_CALLING
490             mPhoneInterfaceManager.handlePinMmiForSubscriber(1, "123456789");
491 
492             // FEATURE_TELEPHONY_RADIO_ACCESS
493             mPhoneInterfaceManager.toggleRadioOnOffForSubscriber(1);
494         } catch (Exception e) {
495             fail("Not expect exception " + e.getMessage());
496         }
497     }
498 
499     @Test
500     @EnableCompatChanges({TelephonyManager.ENABLE_FEATURE_MAPPING})
testWithoutTelephonyFeatureAndCompatChanges()501     public void testWithoutTelephonyFeatureAndCompatChanges() throws Exception {
502         // Replace field to set SDK version of vendor partition to Android V
503         int vendorApiLevel = Build.VERSION_CODES.VANILLA_ICE_CREAM;
504         replaceInstance(PhoneInterfaceManager.class, "mVendorApiLevel", mPhoneInterfaceManager,
505                 vendorApiLevel);
506 
507         // telephony features is not defined, expect UnsupportedOperationException.
508         doReturn(false).when(mPackageManager).hasSystemFeature(
509                 PackageManager.FEATURE_TELEPHONY_CALLING);
510         doReturn(false).when(mPackageManager).hasSystemFeature(
511                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS);
512         mPhoneInterfaceManager.setPackageManager(mPackageManager);
513         doReturn(true).when(mFeatureFlags).enforceTelephonyFeatureMappingForPublicApis();
514         mPhoneInterfaceManager.setFeatureFlags(mFeatureFlags);
515         doNothing().when(mPhoneInterfaceManager).enforceModifyPermission();
516 
517         assertThrows(UnsupportedOperationException.class,
518                 () -> mPhoneInterfaceManager.handlePinMmiForSubscriber(1, "123456789"));
519         assertThrows(UnsupportedOperationException.class,
520                 () -> mPhoneInterfaceManager.toggleRadioOnOffForSubscriber(1));
521     }
522 
523     @Test
testGetCurrentPackageNameWithNoKnownPackage()524     public void testGetCurrentPackageNameWithNoKnownPackage() throws Exception {
525         Field field = PhoneInterfaceManager.class.getDeclaredField("mApp");
526         field.setAccessible(true);
527         Field modifiersField = Field.class.getDeclaredField("accessFlags");
528         modifiersField.setAccessible(true);
529         modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
530         field.set(mPhoneInterfaceManager, mPhoneGlobals);
531 
532         doReturn(mPackageManager).when(mPhoneGlobals).getPackageManager();
533         doReturn(null).when(mPackageManager).getPackagesForUid(anyInt());
534 
535         String packageName = mPhoneInterfaceManager.getCurrentPackageName();
536         assertEquals(null, packageName);
537     }
538 }
539