Enforce map the telephony features with APIs in PhoneInterfaceManager.

If the required telephony feature is not defined, throw UnsupportedOperationException.

Bug: 297989574
Test: atest PhoneInterfaceManagerTest
Change-Id: Ib449aa285d1d1df7dddc1d96c82ef7b07c243a1c
diff --git a/tests/Android.bp b/tests/Android.bp
index 3015f76..a0304f6 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -50,6 +50,7 @@
         "testables",
         "platform-compat-test-rules",
         "flag-junit",
+        "telephony_flags_core_java_lib",
         "satellite-s2storage-rw",
         "satellite-s2storage-testutils",
         "s2-geometry-library-java",
diff --git a/tests/src/com/android/phone/PhoneInterfaceManagerTest.java b/tests/src/com/android/phone/PhoneInterfaceManagerTest.java
index 150703d..a96bc2f 100644
--- a/tests/src/com/android/phone/PhoneInterfaceManagerTest.java
+++ b/tests/src/com/android/phone/PhoneInterfaceManagerTest.java
@@ -20,6 +20,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.doNothing;
@@ -31,8 +32,10 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.compat.testing.PlatformCompatChangeRule;
 import android.content.Context;
 import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.permission.flags.Flags;
 import android.platform.test.flag.junit.SetFlagsRule;
@@ -49,9 +52,12 @@
 import com.android.internal.telephony.flags.FeatureFlags;
 import com.android.internal.telephony.subscription.SubscriptionManagerService;
 
+import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.TestRule;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 
@@ -62,9 +68,14 @@
  */
 @RunWith(AndroidJUnit4.class)
 public class PhoneInterfaceManagerTest extends TelephonyTestBase {
+    @Rule
+    public TestRule compatChangeRule = new PlatformCompatChangeRule();
+
     private PhoneInterfaceManager mPhoneInterfaceManager;
     private SharedPreferences mSharedPreferences;
     private IIntegerConsumer mIIntegerConsumer;
+    private static final String sDebugPackageName =
+            PhoneInterfaceManagerTest.class.getPackageName();
 
     @Mock
     PhoneGlobals mPhoneGlobals;
@@ -72,7 +83,8 @@
     Phone mPhone;
     @Mock
     FeatureFlags mFeatureFlags;
-
+    @Mock
+    PackageManager mPackageManager;
     @Mock
     private SubscriptionManagerService mSubscriptionManagerService;
 
@@ -82,6 +94,8 @@
     @UiThreadTest
     public void setUp() throws Exception {
         super.setUp();
+        doReturn(sDebugPackageName).when(mPhoneGlobals).getOpPackageName();
+
         // Note that PhoneInterfaceManager is a singleton. Calling init gives us a handle to the
         // global singleton, but the context that is passed in is unused if the phone app is already
         // alive on a test devices. You must use the spy to mock behavior. Mocks stemming from the
@@ -93,6 +107,13 @@
         mSharedPreferences = mPhoneInterfaceManager.getSharedPreferences();
         mSharedPreferences.edit().remove(Phone.PREF_NULL_CIPHER_AND_INTEGRITY_ENABLED).commit();
         mIIntegerConsumer = mock(IIntegerConsumer.class);
+
+        // In order not to affect the existing implementation, define a telephony features
+        // and disabled enforce_telephony_feature_mapping_for_public_apis feature flag
+        mPhoneInterfaceManager.setFeatureFlags(mFeatureFlags);
+        doReturn(false).when(mFeatureFlags).enforceTelephonyFeatureMappingForPublicApis();
+        mPhoneInterfaceManager.setPackageManager(mPackageManager);
+        doReturn(true).when(mPackageManager).hasSystemFeature(anyString());
     }
 
     @Test
@@ -359,4 +380,32 @@
         }
         assertEquals("Expected error to be empty, was " + error, error, "");
     }
+
+    @Test
+    @EnableCompatChanges({TelephonyManager.ENABLE_FEATURE_MAPPING})
+    public void testTelephonyFeatureAndCompatChanges() {
+        doNothing().when(mPhoneInterfaceManager).enforceModifyPermission();
+        mPhoneInterfaceManager.setFeatureFlags(mFeatureFlags);
+        doReturn(true).when(mFeatureFlags).enforceTelephonyFeatureMappingForPublicApis();
+        mPhoneInterfaceManager.setPackageManager(mPackageManager);
+        doReturn(true).when(mPackageManager).hasSystemFeature(anyString());
+
+        // Enabled FeatureFlags and ENABLE_FEATURE_MAPPING, telephony features are defined
+        try {
+            // FEATURE_TELEPHONY_CALLING
+            mPhoneInterfaceManager.handlePinMmiForSubscriber(1, "123456789");
+
+            // FEATURE_TELEPHONY_RADIO_ACCESS
+            mPhoneInterfaceManager.toggleRadioOnOffForSubscriber(1);
+        } catch (Exception e) {
+            fail("Not expect exception " + e.getMessage());
+        }
+
+        // telephony features is not defined, expect UnsupportedOperationException.
+        doReturn(false).when(mPackageManager).hasSystemFeature(anyString());
+        assertThrows(UnsupportedOperationException.class,
+                () -> mPhoneInterfaceManager.handlePinMmiForSubscriber(1, "123456789"));
+        assertThrows(UnsupportedOperationException.class,
+                () -> mPhoneInterfaceManager.toggleRadioOnOffForSubscriber(1));
+    }
 }