Merge "Dial CS calls directly in limited service" into main
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 58f2670..801eb12 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -862,7 +862,7 @@
<string name="radioInfo_phone_offhook" msgid="7564601639749936170">"Opkald i gang"</string>
<string name="radioInfo_data_disconnected" msgid="8085447971880814541">"Afbrudt"</string>
<string name="radioInfo_data_connecting" msgid="925092271092152472">"Forbindelsen oprettes"</string>
- <string name="radioInfo_data_connected" msgid="7637335645634239508">"Tilsluttet"</string>
+ <string name="radioInfo_data_connected" msgid="7637335645634239508">"Forbundet"</string>
<string name="radioInfo_data_suspended" msgid="8695262782642002785">"Suspenderet"</string>
<string name="radioInfo_unknown" msgid="5401423738500672850">"Ukendt"</string>
<string name="radioInfo_imei_primary" msgid="5948747378637224400">"Primær"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 4f8e559..febd572 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -165,7 +165,7 @@
<string name="voicemail_default" msgid="6427575113775462077">"आपको सेवा देने वाली कंपनी"</string>
<string name="vm_change_pin_old_pin" msgid="7154951790929009241">"पुराना पिन"</string>
<string name="vm_change_pin_new_pin" msgid="2656200418481288069">"नया पिन"</string>
- <string name="vm_change_pin_progress_message" msgid="626015184502739044">"कृपया प्रतीक्षा करें."</string>
+ <string name="vm_change_pin_progress_message" msgid="626015184502739044">"कृपया इंतज़ार करें."</string>
<string name="vm_change_pin_error_too_short" msgid="1789139338449945483">"नया पिन बहुत छोटा है."</string>
<string name="vm_change_pin_error_too_long" msgid="3634907034310018954">"नया पिन बहुत बड़ा है."</string>
<string name="vm_change_pin_error_too_weak" msgid="8581892952627885719">"नया पिन बहुत कमज़ोर है. किसी सशक्त पासवर्ड में निरंतर क्रम या अंकों का दोहराव नहीं होना चाहिए."</string>
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
index 5eea570..10c516c 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/strings.xml
@@ -19,7 +19,7 @@
<string name="phoneAppLabel" product="tablet" msgid="1916019789885839910">"ମୋବାଇଲ୍ ଡାଟା"</string>
<string name="phoneAppLabel" product="default" msgid="130465039375347763">"ଫୋନ୍ ସେବା"</string>
<string name="emergencyDialerIconLabel" msgid="8668005772339436680">"ଜରୁରୀକାଳିନ ଡାଏଲର୍"</string>
- <string name="phoneIconLabel" msgid="3015941229249651419">"ଫୋନ୍"</string>
+ <string name="phoneIconLabel" msgid="3015941229249651419">"ଫୋନ"</string>
<string name="fdnListLabel" msgid="4119121875004244097">"FDN ତାଲିକା"</string>
<string name="unknown" msgid="8279698889921830815">"ଅଜଣା"</string>
<string name="private_num" msgid="4487990167889159992">"ବ୍ୟକ୍ତିଗତ ନମ୍ବର୍"</string>
diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index 3eafb24..ef71016 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -16,12 +16,15 @@
package com.android.phone;
+import static android.content.pm.PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION;
import static android.service.carrier.CarrierService.ICarrierServiceWrapper.KEY_CONFIG_BUNDLE;
import static android.service.carrier.CarrierService.ICarrierServiceWrapper.RESULT_ERROR;
+import static android.telephony.TelephonyManager.ENABLE_FEATURE_MAPPING;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppOpsManager;
+import android.app.compat.CompatChanges;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -66,6 +69,7 @@
import com.android.internal.telephony.PhoneConfigurationManager;
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.TelephonyPermissions;
+import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
import com.android.internal.telephony.util.ArrayUtils;
import com.android.internal.telephony.util.TelephonyUtils;
@@ -685,12 +689,17 @@
@NonNull private final Handler mHandler;
+ @NonNull private final FeatureFlags mFeatureFlags;
+
+ @NonNull private final PackageManager mPackageManager;
+
/**
* Constructs a CarrierConfigLoader, registers it as a service, and registers a broadcast
* receiver for relevant events.
*/
@VisibleForTesting
- /* package */ CarrierConfigLoader(@NonNull Context context, @NonNull Looper looper) {
+ /* package */ CarrierConfigLoader(@NonNull Context context, @NonNull Looper looper,
+ @NonNull FeatureFlags featureFlags) {
super(PermissionEnforcer.fromContext(context));
mContext = context;
mPlatformCarrierConfigPackage =
@@ -719,6 +728,8 @@
TelephonyManager.from(context).registerCarrierPrivilegesCallback(phoneId,
new HandlerExecutor(mHandler), mCarrierServiceChangeCallbacks[phoneId]);
}
+ mFeatureFlags = featureFlags;
+ mPackageManager = context.getPackageManager();
logd("CarrierConfigLoader has started");
PhoneConfigurationManager.registerForMultiSimConfigChange(
@@ -733,10 +744,11 @@
* This is only done once, at startup, from {@link com.android.phone.PhoneApp#onCreate}.
*/
@NonNull
- /* package */ static CarrierConfigLoader init(@NonNull Context context) {
+ /* package */ static CarrierConfigLoader init(@NonNull Context context,
+ @NonNull FeatureFlags featureFlags) {
synchronized (CarrierConfigLoader.class) {
if (sInstance == null) {
- sInstance = new CarrierConfigLoader(context, Looper.myLooper());
+ sInstance = new CarrierConfigLoader(context, Looper.myLooper(), featureFlags);
// Make this service available through ServiceManager.
TelephonyFrameworkInitializer.getTelephonyServiceManager()
.getCarrierConfigServiceRegisterer().register(sInstance);
@@ -1323,6 +1335,8 @@
return new PersistableBundle();
}
+ enforceTelephonyFeatureWithException(callingPackage, "getConfigForSubIdWithFeature");
+
int phoneId = SubscriptionManager.getPhoneId(subscriptionId);
PersistableBundle retConfig = CarrierConfigManager.getDefaultConfig();
if (SubscriptionManager.isValidPhoneId(phoneId)) {
@@ -1367,6 +1381,9 @@
Objects.requireNonNull(keys, "Config keys must be non-null");
enforceCallerIsSystemOrRequestingPackage(callingPackage);
+ enforceTelephonyFeatureWithException(callingPackage,
+ "getConfigSubsetForSubIdWithFeature");
+
// Permission check is performed inside and an empty bundle will return on failure.
// No SecurityException thrown here since most clients expect to retrieve the overridden
// value if present or use default one if not
@@ -1416,6 +1433,9 @@
throw new IllegalArgumentException(
"Invalid phoneId " + phoneId + " for subId " + subscriptionId);
}
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(), "overrideConfig");
+
// Post to run on handler thread on which all states should be confined.
mHandler.post(() -> {
overrideConfig(mOverrideConfigs, phoneId, overrides);
@@ -1468,6 +1488,9 @@
"Invalid phoneId " + phoneId + " for subId " + subscriptionId);
}
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ "notifyConfigChangedForSubId");
+
logdWithLocalLog("Notified carrier config changed. phoneId=" + phoneId
+ ", subId=" + subscriptionId);
@@ -1488,6 +1511,9 @@
if (!SubscriptionManager.isValidPhoneId(phoneId)) {
throw new IllegalArgumentException("Invalid phoneId: " + phoneId);
}
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(), "updateConfigForPhoneId");
+
// requires Java 7 for switch on string.
switch (simState) {
case IccCardConstants.INTENT_VALUE_ICC_ABSENT:
@@ -1509,6 +1535,10 @@
@NonNull
public String getDefaultCarrierServicePackageName() {
getDefaultCarrierServicePackageName_enforcePermission();
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ "getDefaultCarrierServicePackageName");
+
return mPlatformCarrierConfigPackage;
}
@@ -1819,6 +1849,40 @@
== TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
}
+ /**
+ * Get the current calling package name.
+ * @return the current calling package name
+ */
+ @Nullable
+ private String getCurrentPackageName() {
+ if (mPackageManager == null) return null;
+ String[] callingUids = mPackageManager.getPackagesForUid(Binder.getCallingUid());
+ return (callingUids == null) ? null : callingUids[0];
+ }
+
+ /**
+ * Make sure the device has required telephony feature
+ *
+ * @throws UnsupportedOperationException if the device does not have required telephony feature
+ */
+ private void enforceTelephonyFeatureWithException(@Nullable String callingPackage,
+ @NonNull String methodName) {
+ if (callingPackage == null || mPackageManager == null) {
+ return;
+ }
+
+ if (!mFeatureFlags.enforceTelephonyFeatureMappingForPublicApis()
+ || !CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, callingPackage,
+ Binder.getCallingUserHandle())) {
+ return;
+ }
+
+ if (!mPackageManager.hasSystemFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+ throw new UnsupportedOperationException(
+ methodName + " is unsupported without " + FEATURE_TELEPHONY_SUBSCRIPTION);
+ }
+ }
+
private class CarrierServiceConnection implements ServiceConnection {
final int phoneId;
@NonNull final String pkgName;
diff --git a/src/com/android/phone/ImsRcsController.java b/src/com/android/phone/ImsRcsController.java
index 3f35454..a778f6a 100644
--- a/src/com/android/phone/ImsRcsController.java
+++ b/src/com/android/phone/ImsRcsController.java
@@ -16,7 +16,13 @@
package com.android.phone;
+import static android.content.pm.PackageManager.FEATURE_TELEPHONY_IMS;
+import static android.content.pm.PackageManager.FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION;
+import static android.telephony.TelephonyManager.ENABLE_FEATURE_MAPPING;
+
import android.Manifest;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.compat.CompatChanges;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
@@ -53,6 +59,7 @@
import com.android.internal.telephony.ISipDialogStateCallback;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.TelephonyPermissions;
+import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.ims.ImsResolver;
import com.android.services.telephony.rcs.RcsFeatureController;
import com.android.services.telephony.rcs.SipTransportController;
@@ -74,6 +81,8 @@
private PhoneGlobals mApp;
private TelephonyRcsService mRcsService;
private ImsResolver mImsResolver;
+ private FeatureFlags mFeatureFlags;
+ private PackageManager mPackageManager;
// set by shell cmd phone src set-device-enabled true/false
private Boolean mSingleRegistrationOverride;
@@ -90,10 +99,10 @@
* Initialize the singleton ImsRcsController instance.
* This is only done once, at startup, from PhoneApp.onCreate().
*/
- static ImsRcsController init(PhoneGlobals app) {
+ static ImsRcsController init(PhoneGlobals app, FeatureFlags featureFlags) {
synchronized (ImsRcsController.class) {
if (sInstance == null) {
- sInstance = new ImsRcsController(app);
+ sInstance = new ImsRcsController(app, featureFlags);
} else {
Log.wtf(TAG, "init() called multiple times! sInstance = " + sInstance);
}
@@ -102,9 +111,11 @@
}
/** Private constructor; @see init() */
- private ImsRcsController(PhoneGlobals app) {
+ private ImsRcsController(PhoneGlobals app, FeatureFlags featureFlags) {
Log.i(TAG, "ImsRcsController");
mApp = app;
+ mFeatureFlags = featureFlags;
+ mPackageManager = mApp.getPackageManager();
TelephonyFrameworkInitializer
.getTelephonyServiceManager().getTelephonyImsServiceRegisterer().register(this);
mImsResolver = ImsResolver.getInstance();
@@ -118,6 +129,10 @@
public void registerImsRegistrationCallback(int subId, IImsRegistrationCallback callback) {
TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
mApp, subId, "registerImsRegistrationCallback");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "registerImsRegistrationCallback");
+
final long token = Binder.clearCallingIdentity();
try {
getRcsFeatureController(subId).registerImsRegistrationCallback(subId, callback);
@@ -136,6 +151,10 @@
public void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback callback) {
TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
mApp, subId, "unregisterImsRegistrationCallback");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "unregisterImsRegistrationCallback");
+
final long token = Binder.clearCallingIdentity();
try {
getRcsFeatureController(subId).unregisterImsRegistrationCallback(subId, callback);
@@ -153,6 +172,10 @@
public void getImsRcsRegistrationState(int subId, IIntegerConsumer consumer) {
TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
mApp, subId, "getImsRcsRegistrationState");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "getImsRcsRegistrationState");
+
final long token = Binder.clearCallingIdentity();
try {
getRcsFeatureController(subId).getRegistrationState(regState -> {
@@ -175,6 +198,10 @@
public void getImsRcsRegistrationTransportType(int subId, IIntegerConsumer consumer) {
TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
mApp, subId, "getImsRcsRegistrationTransportType");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "getImsRcsRegistrationTransportType");
+
final long token = Binder.clearCallingIdentity();
try {
getRcsFeatureController(subId).getRegistrationTech(regTech -> {
@@ -204,6 +231,10 @@
@Override
public void registerRcsAvailabilityCallback(int subId, IImsCapabilityCallback callback) {
enforceReadPrivilegedPermission("registerRcsAvailabilityCallback");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "registerRcsAvailabilityCallback");
+
final long token = Binder.clearCallingIdentity();
try {
getRcsFeatureController(subId).registerRcsAvailabilityCallback(subId, callback);
@@ -224,6 +255,10 @@
@Override
public void unregisterRcsAvailabilityCallback(int subId, IImsCapabilityCallback callback) {
enforceReadPrivilegedPermission("unregisterRcsAvailabilityCallback");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "unregisterRcsAvailabilityCallback");
+
final long token = Binder.clearCallingIdentity();
try {
getRcsFeatureController(subId).unregisterRcsAvailabilityCallback(subId, callback);
@@ -247,6 +282,10 @@
@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
@ImsRegistrationImplBase.ImsRegistrationTech int radioTech) {
enforceReadPrivilegedPermission("isCapable");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "isCapable");
+
final long token = Binder.clearCallingIdentity();
try {
return getRcsFeatureController(subId).isCapable(capability, radioTech);
@@ -273,6 +312,10 @@
@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
@ImsRegistrationImplBase.ImsRegistrationTech int radioTech) {
enforceReadPrivilegedPermission("isAvailable");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "isAvailable");
+
final long token = Binder.clearCallingIdentity();
try {
return getRcsFeatureController(subId).isAvailable(capability, radioTech);
@@ -290,6 +333,10 @@
List<Uri> contactNumbers, IRcsUceControllerCallback c) {
enforceAccessUserCapabilityExchangePermission("requestCapabilities");
enforceReadContactsPermission("requestCapabilities");
+
+ enforceTelephonyFeatureWithException(callingPackage,
+ FEATURE_TELEPHONY_IMS, "requestCapabilities");
+
final long token = Binder.clearCallingIdentity();
try {
UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature(
@@ -311,6 +358,10 @@
String callingFeatureId, Uri contactNumber, IRcsUceControllerCallback c) {
enforceAccessUserCapabilityExchangePermission("requestAvailability");
enforceReadContactsPermission("requestAvailability");
+
+ enforceTelephonyFeatureWithException(callingPackage,
+ FEATURE_TELEPHONY_IMS, "requestAvailability");
+
final long token = Binder.clearCallingIdentity();
try {
UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature(
@@ -330,6 +381,10 @@
@Override
public @PublishState int getUcePublishState(int subId) {
enforceReadPrivilegedPermission("getUcePublishState");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "getUcePublishState");
+
final int uid = Binder.getCallingUid();
final long token = Binder.clearCallingIdentity();
boolean isSupportPublishingState = false;
@@ -485,6 +540,10 @@
@Override
public void registerUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c) {
enforceReadPrivilegedPermission("registerUcePublishStateCallback");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "registerUcePublishStateCallback");
+
final int uid = Binder.getCallingUid();
final long token = Binder.clearCallingIdentity();
boolean isSupportPublishingState = false;
@@ -510,6 +569,10 @@
@Override
public void unregisterUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c) {
enforceReadPrivilegedPermission("unregisterUcePublishStateCallback");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "unregisterUcePublishStateCallback");
+
final long token = Binder.clearCallingIdentity();
try {
UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature(
@@ -534,6 +597,10 @@
+ "isUceSettingEnabled");
return false;
}
+
+ enforceTelephonyFeatureWithException(callingPackage,
+ FEATURE_TELEPHONY_IMS, "isUceSettingEnabled");
+
final long token = Binder.clearCallingIdentity();
try {
return SubscriptionManager.getBooleanSubscriptionProperty(subId,
@@ -546,6 +613,10 @@
@Override
public void setUceSettingEnabled(int subId, boolean isEnabled) {
enforceModifyPermission();
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "setUceSettingEnabled");
+
final long token = Binder.clearCallingIdentity();
try {
SubscriptionManager.setSubscriptionProperty(subId,
@@ -680,6 +751,10 @@
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
}
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION, "registerSipDialogStateCallback");
+
try {
SipTransportController transport = getRcsFeatureController(subId).getFeature(
SipTransportController.class);
@@ -707,6 +782,10 @@
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
}
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION, "unregisterSipDialogStateCallback");
+
try {
SipTransportController transport = getRcsFeatureController(subId).getFeature(
SipTransportController.class);
@@ -897,6 +976,40 @@
PackageManager.FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION);
}
+ /**
+ * Get the current calling package name.
+ * @return the current calling package name
+ */
+ @Nullable
+ private String getCurrentPackageName() {
+ if (mPackageManager == null) return null;
+ String[] callingUids = mPackageManager.getPackagesForUid(Binder.getCallingUid());
+ return (callingUids == null) ? null : callingUids[0];
+ }
+
+ /**
+ * Make sure the device has required telephony feature
+ *
+ * @throws UnsupportedOperationException if the device does not have required telephony feature
+ */
+ private void enforceTelephonyFeatureWithException(@Nullable String callingPackage,
+ @NonNull String telephonyFeature, @NonNull String methodName) {
+ if (callingPackage == null || mPackageManager == null) {
+ return;
+ }
+
+ if (!mFeatureFlags.enforceTelephonyFeatureMappingForPublicApis()
+ || !CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, callingPackage,
+ Binder.getCallingUserHandle())) {
+ return;
+ }
+
+ if (!mPackageManager.hasSystemFeature(telephonyFeature)) {
+ throw new UnsupportedOperationException(
+ methodName + " is unsupported without " + telephonyFeature);
+ }
+ }
+
void setRcsService(TelephonyRcsService rcsService) {
mRcsService = rcsService;
}
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index f93b1e5..2f372ce 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -576,9 +576,9 @@
phoneMgr = PhoneInterfaceManager.init(this, mFeatureFlags);
- imsRcsController = ImsRcsController.init(this);
+ imsRcsController = ImsRcsController.init(this, mFeatureFlags);
- configLoader = CarrierConfigLoader.init(this);
+ configLoader = CarrierConfigLoader.init(this, mFeatureFlags);
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS)) {
mImsStateCallbackController =
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 8f3281c..01ba40a 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -16,8 +16,11 @@
package com.android.phone;
+import static android.content.pm.PackageManager.FEATURE_TELEPHONY_IMS;
+import static android.content.pm.PackageManager.FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.permission.flags.Flags.opEnableMobileDataByUser;
+import static android.telephony.TelephonyManager.ENABLE_FEATURE_MAPPING;
import static android.telephony.TelephonyManager.HAL_SERVICE_NETWORK;
import static android.telephony.TelephonyManager.HAL_SERVICE_RADIO;
@@ -409,7 +412,7 @@
private static List<String> sThermalMitigationAllowlistedPackages = new ArrayList<>();
private final PhoneGlobals mApp;
- private final FeatureFlags mFeatureFlags;
+ private FeatureFlags mFeatureFlags;
private final CallManager mCM;
private final ImsResolver mImsResolver;
@@ -420,11 +423,11 @@
private final SharedPreferences mTelephonySharedPreferences;
private final PhoneConfigurationManager mPhoneConfigurationManager;
private final RadioInterfaceCapabilityController mRadioInterfaceCapabilities;
+ private PackageManager mPackageManager;
/** User Activity */
private final AtomicBoolean mNotifyUserActivity;
private static final int USER_ACTIVITY_NOTIFICATION_DELAY = 200;
-
private final Set<Integer> mCarrierPrivilegeTestOverrideSubIds = new ArraySet<>();
private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_";
@@ -2460,6 +2463,7 @@
mPhoneConfigurationManager = PhoneConfigurationManager.getInstance();
mRadioInterfaceCapabilities = RadioInterfaceCapabilityController.getInstance();
mNotifyUserActivity = new AtomicBoolean(false);
+ mPackageManager = app.getPackageManager();
PropertyInvalidatedCache.invalidateCache(TelephonyManager.CACHE_KEY_PHONE_ACCOUNT_TO_SUBID);
publish();
CarrierAllowListInfo.loadInstance(mApp);
@@ -2554,6 +2558,9 @@
}
public void dial(String number) {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CALLING, "dial");
+
dialForSubscriber(getPreferredVoiceSubscription(), number);
}
@@ -2599,6 +2606,9 @@
return;
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_CALLING, "call");
+
final long identity = Binder.clearCallingIdentity();
try {
String url = createTelUrl(number);
@@ -2642,6 +2652,10 @@
public int[] supplyPinReportResultForSubscriber(int subId, String pin) {
enforceModifyPermission();
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
+ "supplyPinReportResultForSubscriber");
+
final long identity = Binder.clearCallingIdentity();
try {
Phone phone = getPhone(subId);
@@ -2656,6 +2670,9 @@
public int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin) {
enforceModifyPermission();
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "supplyPukForSubscriber");
+
final long identity = Binder.clearCallingIdentity();
try {
Phone phone = getPhone(subId);
@@ -2861,6 +2878,9 @@
return false;
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "isRadioOnWithFeature");
+
final long identity = Binder.clearCallingIdentity();
try {
return isRadioOnForSubscriber(subId);
@@ -2890,6 +2910,9 @@
public void toggleRadioOnOffForSubscriber(int subId) {
enforceModifyPermission();
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "toggleRadioOnOffForSubscriber");
+
final long identity = Binder.clearCallingIdentity();
try {
final Phone phone = getPhone(subId);
@@ -2925,6 +2948,10 @@
public boolean needMobileRadioShutdown() {
enforceReadPrivilegedPermission("needMobileRadioShutdown");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "needMobileRadioShutdown");
+
/*
* If any of the Radios are available, it will need to be
* shutdown. So return true if any Radio is available.
@@ -2946,6 +2973,9 @@
public void shutdownMobileRadios() {
enforceModifyPermission();
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "shutdownMobileRadios");
+
final long identity = Binder.clearCallingIdentity();
try {
for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
@@ -3027,6 +3057,9 @@
@TelephonyManager.RadioPowerReason int reason) {
enforceModifyPermission();
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "requestRadioPowerOffForReason");
+
log("requestRadioPowerOffForReason: subId=" + subId
+ ",reason=" + reason + ",callingPackage=" + getCurrentPackageName());
final long identity = Binder.clearCallingIdentity();
@@ -3057,6 +3090,9 @@
@TelephonyManager.RadioPowerReason int reason) {
enforceModifyPermission();
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "clearRadioPowerOffForReason");
+
final long identity = Binder.clearCallingIdentity();
try {
boolean result = false;
@@ -3084,6 +3120,9 @@
public List getRadioPowerOffReasons(int subId, String callingPackage, String callingFeatureId) {
enforceReadPrivilegedPermission("getRadioPowerOffReasons");
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getRadioPowerOffReasons");
+
final long identity = Binder.clearCallingIdentity();
List result = new ArrayList();
try {
@@ -3109,6 +3148,9 @@
public boolean enableDataConnectivity(String callingPackage) {
enforceModifyPermission();
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_DATA, "enableDataConnectivity");
+
final long identity = Binder.clearCallingIdentity();
try {
int subId = SubscriptionManager.getDefaultDataSubscriptionId();
@@ -3130,6 +3172,9 @@
public boolean disableDataConnectivity(String callingPackage) {
enforceModifyPermission();
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_DATA, "disableDataConnectivity");
+
final long identity = Binder.clearCallingIdentity();
try {
int subId = SubscriptionManager.getDefaultDataSubscriptionId();
@@ -3148,6 +3193,9 @@
@Override
public boolean isDataConnectivityPossible(int subId) {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_DATA, "isDataConnectivityPossible");
+
final long identity = Binder.clearCallingIdentity();
try {
final Phone phone = getPhone(subId);
@@ -3168,6 +3216,9 @@
public void handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback) {
enforceCallPermission();
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "handleUssdRequest");
+
final long identity = Binder.clearCallingIdentity();
try {
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
@@ -3183,6 +3234,9 @@
public boolean handlePinMmiForSubscriber(int subId, String dialString) {
enforceModifyPermission();
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CALLING, "handlePinMmiForSubscriber");
+
final long identity = Binder.clearCallingIdentity();
try {
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
@@ -3230,6 +3284,10 @@
+ "targeting API level 31+.");
}
}
+
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_CALLING, "getCallStateForSubscription");
+
final long identity = Binder.clearCallingIdentity();
try {
Phone phone = getPhone(subId);
@@ -3247,6 +3305,9 @@
@Override
public int getDataStateForSubId(int subId) {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_DATA, "getDataStateForSubId");
+
final long identity = Binder.clearCallingIdentity();
try {
final Phone phone = getPhone(subId);
@@ -3268,6 +3329,9 @@
@Override
public @DataActivityType int getDataActivityForSubId(int subId) {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_DATA, "getDataActivityForSubId");
+
final long identity = Binder.clearCallingIdentity();
try {
final Phone phone = getPhone(subId);
@@ -3305,6 +3369,9 @@
? new CellIdentityCdma() : new CellIdentityGsm();
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getCellLocation");
+
WorkSource workSource = getWorkSource(Binder.getCallingUid());
final long identity = Binder.clearCallingIdentity();
try {
@@ -3318,6 +3385,9 @@
@Override
public String getNetworkCountryIsoForPhone(int phoneId) {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getNetworkCountryIsoForPhone");
+
// Reporting the correct network country is ambiguous when IWLAN could conflict with
// registered cell info, so return a NULL country instead.
final long identity = Binder.clearCallingIdentity();
@@ -3388,6 +3458,9 @@
return null;
}
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getNeighboringCellInfo");
+
if (DBG_LOC) log("getNeighboringCellInfo: is active user");
List<CellInfo> info = getAllCellInfo(callingPackage, callingFeatureId);
@@ -3441,6 +3514,9 @@
return getCachedCellInfo();
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getAllCellInfo");
+
if (DBG_LOC) log("getAllCellInfo: is active user");
WorkSource workSource = getWorkSource(Binder.getCallingUid());
final long identity = Binder.clearCallingIdentity();
@@ -3509,6 +3585,8 @@
return;
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "requestCellInfoUpdateInternal");
final Phone phone = getPhoneFromSubId(subId);
if (phone == null) throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
@@ -3547,6 +3625,9 @@
return null;
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_GSM, "getImeiForSlot");
+
final long identity = Binder.clearCallingIdentity();
try {
return phone.getImei();
@@ -3562,6 +3643,10 @@
callingFeatureId, "getPrimaryImei")) {
throw new SecurityException("Caller does not have permission");
}
+
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_GSM, "getPrimaryImei");
+
final long identity = Binder.clearCallingIdentity();
try {
for (Phone phone : PhoneFactory.getPhones()) {
@@ -3577,6 +3662,9 @@
@Override
public String getTypeAllocationCodeForSlot(int slotIndex) {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_GSM, "getTypeAllocationCodeForSlot");
+
Phone phone = PhoneFactory.getPhone(slotIndex);
String tac = null;
if (phone != null) {
@@ -3611,6 +3699,9 @@
return null;
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_CDMA, "getMeidForSlot");
+
final long identity = Binder.clearCallingIdentity();
try {
return phone.getMeid();
@@ -3621,6 +3712,9 @@
@Override
public String getManufacturerCodeForSlot(int slotIndex) {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CDMA, "getManufacturerCodeForSlot");
+
Phone phone = PhoneFactory.getPhone(slotIndex);
String manufacturerCode = null;
if (phone != null) {
@@ -3650,6 +3744,9 @@
return null;
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY, "getDeviceSoftwareVersionForSlot");
+
final long identity = Binder.clearCallingIdentity();
try {
return phone.getDeviceSvn();
@@ -3660,6 +3757,9 @@
@Override
public int getSubscriptionCarrierId(int subId) {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getSubscriptionCarrierId");
+
final long identity = Binder.clearCallingIdentity();
try {
final Phone phone = getPhone(subId);
@@ -3671,6 +3771,9 @@
@Override
public String getSubscriptionCarrierName(int subId) {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getSubscriptionCarrierName");
+
final long identity = Binder.clearCallingIdentity();
try {
final Phone phone = getPhone(subId);
@@ -3682,6 +3785,9 @@
@Override
public int getSubscriptionSpecificCarrierId(int subId) {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getSubscriptionSpecificCarrierId");
+
final long identity = Binder.clearCallingIdentity();
try {
final Phone phone = getPhone(subId);
@@ -3694,6 +3800,10 @@
@Override
public String getSubscriptionSpecificCarrierName(int subId) {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
+ "getSubscriptionSpecificCarrierName");
+
final long identity = Binder.clearCallingIdentity();
try {
final Phone phone = getPhone(subId);
@@ -3712,6 +3822,10 @@
if (phone == null) {
return TelephonyManager.UNKNOWN_CARRIER_ID;
}
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getCarrierIdFromMccMnc");
+
final long identity = Binder.clearCallingIdentity();
try {
return CarrierResolver.getCarrierIdFromMccMnc(phone.getContext(), mccmnc);
@@ -3832,6 +3946,9 @@
@Override
public int getActivePhoneTypeForSlot(int slotIndex) {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY, "getActivePhoneTypeForSlot");
+
final long identity = Binder.clearCallingIdentity();
try {
final Phone phone = PhoneFactory.getPhone(slotIndex);
@@ -3863,6 +3980,10 @@
return -1;
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_CDMA,
+ "getCdmaEriIconIndexForSubscriber");
+
final long identity = Binder.clearCallingIdentity();
try {
final Phone phone = getPhone(subId);
@@ -3948,6 +4069,9 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mApp, subId, "getCdmaMdn");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CDMA, "getCdmaMdn");
+
final long identity = Binder.clearCallingIdentity();
try {
final Phone phone = getPhone(subId);
@@ -3970,6 +4094,9 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mApp, subId, "getCdmaMin");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CDMA, "getCdmaMin");
+
final long identity = Binder.clearCallingIdentity();
try {
final Phone phone = getPhone(subId);
@@ -3999,6 +4126,9 @@
+ ", configured package: " + authorizedPackage);
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_CALLING, "requestNumberVerification");
+
if (range == null) {
throw new NullPointerException("Range must be non-null");
}
@@ -4013,6 +4143,9 @@
* Returns true if CDMA provisioning needs to run.
*/
public boolean needsOtaServiceProvisioning() {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "needsOtaServiceProvisioning");
+
final long identity = Binder.clearCallingIdentity();
try {
return getDefaultPhone().needsOtaServiceProvisioning();
@@ -4029,6 +4162,9 @@
TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
mApp, subId, "setVoiceMailNumber");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CALLING, "setVoiceMailNumber");
+
final long identity = Binder.clearCallingIdentity();
try {
Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER,
@@ -4048,6 +4184,9 @@
throw new SecurityException("caller must be system dialer");
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_CALLING, "getVisualVoicemailSettings");
+
final long identity = Binder.clearCallingIdentity();
try {
PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter.fromSubId(subId);
@@ -4070,6 +4209,9 @@
return null;
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_CALLING, "getVisualVoicemailPackageName");
+
final long identity = Binder.clearCallingIdentity();
try {
return RemoteVvmTaskManager.getRemotePackage(mApp, subId).getPackageName();
@@ -4083,6 +4225,9 @@
VisualVoicemailSmsFilterSettings settings) {
mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_CALLING, "enableVisualVoicemailSmsFilter");
+
final long identity = Binder.clearCallingIdentity();
try {
VisualVoicemailSmsFilterConfig.enableVisualVoicemailSmsFilter(
@@ -4096,6 +4241,9 @@
public void disableVisualVoicemailSmsFilter(String callingPackage, int subId) {
mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_CALLING, "disableVisualVoicemailSmsFilter");
+
final long identity = Binder.clearCallingIdentity();
try {
VisualVoicemailSmsFilterConfig.disableVisualVoicemailSmsFilter(
@@ -4139,6 +4287,10 @@
mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
enforceVisualVoicemailPackage(callingPackage, subId);
enforceSendSmsPermission();
+
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_CALLING, "sendVisualVoicemailSmsForSubscriber");
+
SmsController smsController = PhoneFactory.getSmsController();
smsController.sendVisualVoicemailSmsForSubscriber(callingPackage, callingAttributionTag,
subId, number, port, text, sentIntent);
@@ -4152,6 +4304,9 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mApp, subId, "setVoiceActivationState");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CALLING, "setVoiceActivationState");
+
final long identity = Binder.clearCallingIdentity();
try {
final Phone phone = getPhone(subId);
@@ -4173,6 +4328,9 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mApp, subId, "setDataActivationState");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_DATA, "setDataActivationState");
+
final long identity = Binder.clearCallingIdentity();
try {
final Phone phone = getPhone(subId);
@@ -4193,6 +4351,9 @@
public int getVoiceActivationState(int subId, String callingPackage) {
enforceReadPrivilegedPermission("getVoiceActivationState");
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_CALLING, "getVoiceActivationState");
+
final Phone phone = getPhone(subId);
final long identity = Binder.clearCallingIdentity();
try {
@@ -4213,6 +4374,9 @@
public int getDataActivationState(int subId, String callingPackage) {
enforceReadPrivilegedPermission("getDataActivationState");
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_DATA, "getDataActivationState");
+
final Phone phone = getPhone(subId);
final long identity = Binder.clearCallingIdentity();
try {
@@ -4256,6 +4420,9 @@
*/
@Override
public boolean isConcurrentVoiceAndDataAllowed(int subId) {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_DATA, "isConcurrentVoiceAndDataAllowed");
+
final long identity = Binder.clearCallingIdentity();
try {
return getPhoneFromSubIdOrDefault(subId).isConcurrentVoiceAndDataAllowed();
@@ -4280,6 +4447,9 @@
getDefaultSubscription(), "sendDialerSpecialCode");
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_CALLING, "sendDialerSpecialCode");
+
final long identity = Binder.clearCallingIdentity();
try {
defaultPhone.sendDialerSpecialCode(inputCode);
@@ -4293,6 +4463,10 @@
TelephonyPermissions
.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
mApp, subId, "getNetworkSelectionMode");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getNetworkSelectionMode");
+
final long identity = Binder.clearCallingIdentity();
try {
if (!isActiveSubscription(subId)) {
@@ -4307,6 +4481,10 @@
@Override
public boolean isInEmergencySmsMode() {
enforceReadPrivilegedPermission("isInEmergencySmsMode");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_MESSAGING, "isInEmergencySmsMode");
+
final long identity = Binder.clearCallingIdentity();
try {
for (Phone phone : PhoneFactory.getPhones()) {
@@ -4601,6 +4779,10 @@
@Override
public boolean isCapable(int subId, int capability, int regTech) {
enforceReadPrivilegedPermission("isCapable");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "isCapable");
+
final long token = Binder.clearCallingIdentity();
try {
int slotId = getSlotIndexOrException(subId);
@@ -4620,6 +4802,10 @@
@Override
public boolean isAvailable(int subId, int capability, int regTech) {
enforceReadPrivilegedPermission("isAvailable");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "isAvailable");
+
final long token = Binder.clearCallingIdentity();
try {
Phone phone = getPhone(subId);
@@ -4683,6 +4869,9 @@
TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
mApp, subId, "isAdvancedCallingSettingEnabled");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "isAdvancedCallingSettingEnabled");
+
final long token = Binder.clearCallingIdentity();
try {
int slotId = getSlotIndexOrException(subId);
@@ -4699,6 +4888,10 @@
public void setAdvancedCallingSettingEnabled(int subId, boolean isEnabled) {
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
"setAdvancedCallingSettingEnabled");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "setAdvancedCallingSettingEnabled");
+
final long identity = Binder.clearCallingIdentity();
try {
int slotId = getSlotIndexOrException(subId);
@@ -4720,6 +4913,10 @@
public boolean isVtSettingEnabled(int subId) {
TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
mApp, subId, "isVtSettingEnabled");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "isVtSettingEnabled");
+
final long identity = Binder.clearCallingIdentity();
try {
int slotId = getSlotIndexOrException(subId);
@@ -4736,6 +4933,10 @@
public void setVtSettingEnabled(int subId, boolean isEnabled) {
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
"setVtSettingEnabled");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "setVtSettingEnabled");
+
final long identity = Binder.clearCallingIdentity();
try {
int slotId = getSlotIndexOrException(subId);
@@ -4757,6 +4958,10 @@
public boolean isVoWiFiSettingEnabled(int subId) {
TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
mApp, subId, "isVoWiFiSettingEnabled");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "isVoWiFiSettingEnabled");
+
final long identity = Binder.clearCallingIdentity();
try {
int slotId = getSlotIndexOrException(subId);
@@ -4773,6 +4978,10 @@
public void setVoWiFiSettingEnabled(int subId, boolean isEnabled) {
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
"setVoWiFiSettingEnabled");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "setVoWiFiSettingEnabled");
+
final long identity = Binder.clearCallingIdentity();
try {
int slotId = getSlotIndexOrException(subId);
@@ -4795,6 +5004,10 @@
public boolean isCrossSimCallingEnabledByUser(int subId) {
TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
mApp, subId, "isCrossSimCallingEnabledByUser");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "isCrossSimCallingEnabledByUser");
+
final long identity = Binder.clearCallingIdentity();
try {
int slotId = getSlotIndexOrException(subId);
@@ -4818,6 +5031,10 @@
public void setCrossSimCallingEnabled(int subId, boolean isEnabled) {
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
"setCrossSimCallingEnabled");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "setCrossSimCallingEnabled");
+
final long identity = Binder.clearCallingIdentity();
try {
int slotId = getSlotIndexOrException(subId);
@@ -4840,6 +5057,10 @@
public boolean isVoWiFiRoamingSettingEnabled(int subId) {
TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
mApp, subId, "isVoWiFiRoamingSettingEnabled");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "isVoWiFiRoamingSettingEnabled");
+
final long identity = Binder.clearCallingIdentity();
try {
int slotId = getSlotIndexOrException(subId);
@@ -4856,6 +5077,10 @@
public void setVoWiFiRoamingSettingEnabled(int subId, boolean isEnabled) {
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
"setVoWiFiRoamingSettingEnabled");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "setVoWiFiRoamingSettingEnabled");
+
final long identity = Binder.clearCallingIdentity();
try {
int slotId = getSlotIndexOrException(subId);
@@ -4873,6 +5098,10 @@
public void setVoWiFiNonPersistent(int subId, boolean isCapable, int mode) {
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
"setVoWiFiNonPersistent");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "setVoWiFiNonPersistent");
+
final long identity = Binder.clearCallingIdentity();
try {
int slotId = getSlotIndexOrException(subId);
@@ -4893,6 +5122,10 @@
public int getVoWiFiModeSetting(int subId) {
TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
mApp, subId, "getVoWiFiModeSetting");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "getVoWiFiModeSetting");
+
final long identity = Binder.clearCallingIdentity();
try {
int slotId = getSlotIndexOrException(subId);
@@ -4909,6 +5142,10 @@
public void setVoWiFiModeSetting(int subId, int mode) {
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
"setVoWiFiModeSetting");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "setVoWiFiModeSetting");
+
final long identity = Binder.clearCallingIdentity();
try {
int slotId = getSlotIndexOrException(subId);
@@ -4925,6 +5162,10 @@
@Override
public int getVoWiFiRoamingModeSetting(int subId) {
enforceReadPrivilegedPermission("getVoWiFiRoamingModeSetting");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "getVoWiFiRoamingModeSetting");
+
final long identity = Binder.clearCallingIdentity();
try {
int slotId = getSlotIndexOrException(subId);
@@ -4941,6 +5182,10 @@
public void setVoWiFiRoamingModeSetting(int subId, int mode) {
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
"setVoWiFiRoamingModeSetting");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "setVoWiFiRoamingModeSetting");
+
final long identity = Binder.clearCallingIdentity();
try {
int slotId = getSlotIndexOrException(subId);
@@ -4958,6 +5203,10 @@
public void setRttCapabilitySetting(int subId, boolean isEnabled) {
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
"setRttCapabilityEnabled");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "setRttCapabilitySetting");
+
final long identity = Binder.clearCallingIdentity();
try {
int slotId = getSlotIndexOrException(subId);
@@ -4979,6 +5228,10 @@
public boolean isTtyOverVolteEnabled(int subId) {
TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
mApp, subId, "isTtyOverVolteEnabled");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "isTtyOverVolteEnabled");
+
final long identity = Binder.clearCallingIdentity();
try {
int slotId = getSlotIndexOrException(subId);
@@ -5104,6 +5357,9 @@
boolean isProvisioned) {
checkModifyPhoneStatePermission(subId, "setRcsProvisioningStatusForCapability");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "setRcsProvisioningStatusForCapability");
+
final long identity = Binder.clearCallingIdentity();
try {
ImsProvisioningController controller = ImsProvisioningController.getInstance();
@@ -5124,6 +5380,9 @@
TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
mApp, subId, "getRcsProvisioningStatusForCapability");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "getRcsProvisioningStatusForCapability");
+
final long identity = Binder.clearCallingIdentity();
try {
ImsProvisioningController controller = ImsProvisioningController.getInstance();
@@ -5144,6 +5403,9 @@
boolean isProvisioned) {
checkModifyPhoneStatePermission(subId, "setImsProvisioningStatusForCapability");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "setImsProvisioningStatusForCapability");
+
final long identity = Binder.clearCallingIdentity();
try {
ImsProvisioningController controller = ImsProvisioningController.getInstance();
@@ -5163,6 +5425,9 @@
TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
mApp, subId, "getProvisioningStatusForCapability");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "getImsProvisioningStatusForCapability");
+
final long identity = Binder.clearCallingIdentity();
try {
ImsProvisioningController controller = ImsProvisioningController.getInstance();
@@ -5183,6 +5448,9 @@
TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
mApp, subId, "isProvisioningRequiredForCapability");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "isProvisioningRequiredForCapability");
+
final long identity = Binder.clearCallingIdentity();
try {
ImsProvisioningController controller = ImsProvisioningController.getInstance();
@@ -5203,6 +5471,9 @@
TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
mApp, subId, "isProvisioningRequiredForCapability");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "isRcsProvisioningRequiredForCapability");
+
final long identity = Binder.clearCallingIdentity();
try {
ImsProvisioningController controller = ImsProvisioningController.getInstance();
@@ -5226,6 +5497,9 @@
TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
mApp, subId, "getImsProvisioningInt");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "getImsProvisioningInt");
+
final long identity = Binder.clearCallingIdentity();
try {
// TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
@@ -5266,6 +5540,9 @@
TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
mApp, subId, "getImsProvisioningString");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "getImsProvisioningString");
+
final long identity = Binder.clearCallingIdentity();
try {
// TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
@@ -5293,6 +5570,9 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
"setImsProvisioningInt");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "setImsProvisioningInt");
+
final long identity = Binder.clearCallingIdentity();
try {
// TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
@@ -5332,6 +5612,10 @@
}
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
"setImsProvisioningString");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS, "setImsProvisioningString");
+
final long identity = Binder.clearCallingIdentity();
try {
// TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
@@ -5405,6 +5689,9 @@
return TelephonyManager.NETWORK_TYPE_UNKNOWN;
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getNetworkTypeForSubscriber");
+
final long identity = Binder.clearCallingIdentity();
try {
final Phone phone = getPhone(subId);
@@ -5442,6 +5729,9 @@
}
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getDataNetworkTypeForSubscriber");
+
final long identity = Binder.clearCallingIdentity();
try {
final Phone phone = getPhone(subId);
@@ -5470,6 +5760,9 @@
}
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_CALLING, "getVoiceNetworkTypeForSubscriber");
+
final long identity = Binder.clearCallingIdentity();
try {
final Phone phone = getPhone(subId);
@@ -5497,6 +5790,9 @@
*/
@Override
public boolean hasIccCardUsingSlotIndex(int slotIndex) {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "hasIccCardUsingSlotIndex");
+
final long identity = Binder.clearCallingIdentity();
try {
final Phone phone = PhoneFactory.getPhone(slotIndex);
@@ -5534,6 +5830,9 @@
return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getLteOnCdmaModeForSubscriber");
+
final long identity = Binder.clearCallingIdentity();
try {
final Phone phone = getPhone(subId);
@@ -5615,6 +5914,7 @@
@Override
public IccOpenLogicalChannelResponse iccOpenLogicalChannel(
@NonNull IccLogicalChannelRequest request) {
+
Phone phone = getPhoneFromValidIccLogicalChannelRequest(request,
/*message=*/ "iccOpenLogicalChannel");
@@ -5622,6 +5922,9 @@
// Verify that the callingPackage in the request belongs to the calling UID
mAppOps.checkPackage(Binder.getCallingUid(), request.callingPackage);
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "iccOpenLogicalChannel");
+
return iccOpenLogicalChannelWithPermission(phone, request);
}
@@ -5668,6 +5971,9 @@
@Override
public boolean iccCloseLogicalChannel(@NonNull IccLogicalChannelRequest request) {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "iccCloseLogicalChannel");
+
Phone phone = getPhoneFromValidIccLogicalChannelRequest(request,
/*message=*/"iccCloseLogicalChannel");
@@ -5715,6 +6021,10 @@
int command, int p1, int p2, int p3, String data) {
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mApp, subId, "iccTransmitApduLogicalChannel");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "iccTransmitApduLogicalChannel");
+
if (DBG) {
log("iccTransmitApduLogicalChannel: subId=" + subId + " chnl=" + channel
+ " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
@@ -5728,6 +6038,11 @@
public String iccTransmitApduLogicalChannelByPort(int slotIndex, int portIndex, int channel,
int cla, int command, int p1, int p2, int p3, String data) {
enforceModifyPermission();
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
+ "iccTransmitApduLogicalChannelBySlot");
+
if (DBG) {
log("iccTransmitApduLogicalChannelByPort: slotIndex=" + slotIndex + " portIndex="
+ portIndex + " chnl=" + channel + " cla=" + cla + " cmd=" + command + " p1="
@@ -5769,6 +6084,10 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mApp, subId, "iccTransmitApduBasicChannel");
mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "iccTransmitApduBasicChannel");
+
if (DBG) {
log("iccTransmitApduBasicChannel: subId=" + subId + " cla=" + cla + " cmd="
+ command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
@@ -5782,6 +6101,10 @@
String callingPackage, int cla, int command, int p1, int p2, int p3, String data) {
enforceModifyPermission();
mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "iccTransmitApduBasicChannelBySlot");
+
if (DBG) {
log("iccTransmitApduBasicChannelByPort: slotIndex=" + slotIndex + " portIndex="
+ portIndex + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2="
@@ -5834,6 +6157,9 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mApp, subId, "iccExchangeSimIO");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "iccExchangeSimIO");
+
final long identity = Binder.clearCallingIdentity();
try {
if (DBG) {
@@ -5879,6 +6205,9 @@
return null;
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getForbiddenPlmns");
+
final long identity = Binder.clearCallingIdentity();
try {
if (appType != TelephonyManager.APPTYPE_USIM
@@ -5915,6 +6244,9 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mApp, subId, "setForbiddenPlmns");
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "setForbiddenPlmns");
+
if (appType != TelephonyManager.APPTYPE_USIM && appType != TelephonyManager.APPTYPE_SIM) {
loge("setForbiddenPlmnList(): App Type must be USIM or SIM");
throw new IllegalArgumentException("Invalid appType: App Type must be USIM or SIM");
@@ -5944,6 +6276,9 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mApp, subId, "sendEnvelopeWithStatus");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "sendEnvelopeWithStatus");
+
final long identity = Binder.clearCallingIdentity();
try {
IccIoResult response = (IccIoResult) sendRequest(CMD_SEND_ENVELOPE, content, subId);
@@ -6049,6 +6384,9 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mApp, phone.getSubId(), "resetModemConfig");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "resetModemConfig");
+
final long identity = Binder.clearCallingIdentity();
try {
Boolean success = (Boolean) sendRequest(CMD_RESET_MODEM_CONFIG, null);
@@ -6075,6 +6413,9 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mApp, phone.getSubId(), "rebootModem");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "rebootModem");
+
final long identity = Binder.clearCallingIdentity();
try {
Boolean success = (Boolean) sendRequest(CMD_MODEM_REBOOT, null);
@@ -6095,6 +6436,9 @@
public void resetIms(int slotIndex) {
enforceModifyPermission();
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_IMS, "resetIms");
+
final long identity = Binder.clearCallingIdentity();
try {
if (mImsResolver == null) {
@@ -6374,6 +6718,9 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mApp, subId, "setNetworkSelectionModeAutomatic");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "setNetworkSelectionModeAutomatic");
+
final long identity = Binder.clearCallingIdentity();
try {
if (!isActiveSubscription(subId)) {
@@ -6404,6 +6751,9 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mApp, subId, "setNetworkSelectionModeManual");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "setNetworkSelectionModeManual");
+
final long identity = Binder.clearCallingIdentity();
if (!isActiveSubscription(subId)) {
return false;
@@ -6434,6 +6784,9 @@
.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
mApp, subId, "getManualNetworkSelectionPlmn");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getManualNetworkSelectionPlmn");
+
final long identity = Binder.clearCallingIdentity();
try {
if (!isActiveSubscription(subId)) {
@@ -6496,6 +6849,10 @@
public void getCallForwarding(int subId, int callForwardingReason,
ICallForwardingInfoCallback callback) {
enforceReadPrivilegedPermission("getCallForwarding");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CALLING, "getCallForwarding");
+
long identity = Binder.clearCallingIdentity();
try {
if (DBG) {
@@ -6548,6 +6905,10 @@
public void setCallForwarding(int subId, CallForwardingInfo callForwardingInfo,
IIntegerConsumer callback) {
enforceModifyPermission();
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CALLING, "setCallForwarding");
+
long identity = Binder.clearCallingIdentity();
try {
if (DBG) {
@@ -6581,6 +6942,10 @@
@Override
public void getCallWaitingStatus(int subId, IIntegerConsumer callback) {
enforceReadPrivilegedPermission("getCallWaitingStatus");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CALLING, "getCallWaitingStatus");
+
long identity = Binder.clearCallingIdentity();
try {
Phone phone = getPhone(subId);
@@ -6632,6 +6997,10 @@
@Override
public void setCallWaitingStatus(int subId, boolean enable, IIntegerConsumer callback) {
enforceModifyPermission();
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CALLING, "setCallWaitingStatus");
+
long identity = Binder.clearCallingIdentity();
try {
if (DBG) log("setCallWaitingStatus: subId " + subId + " enable: " + enable);
@@ -6728,6 +7097,10 @@
}
}
}
+
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "requestNetworkScan");
+
int callingUid = Binder.getCallingUid();
int callingPid = Binder.getCallingPid();
final long identity = Binder.clearCallingIdentity();
@@ -6803,6 +7176,9 @@
.enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
mApp, subId, "getAllowedNetworkTypesBitmask");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getAllowedNetworkTypesBitmask");
+
final long identity = Binder.clearCallingIdentity();
try {
if (DBG) log("getAllowedNetworkTypesBitmask");
@@ -6827,6 +7203,10 @@
@TelephonyManager.AllowedNetworkTypesReason int reason) {
TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
mApp, subId, "getAllowedNetworkTypesForReason");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getAllowedNetworkTypesForReason");
+
final long identity = Binder.clearCallingIdentity();
try {
return getPhoneFromSubIdOrDefault(subId).getAllowedNetworkTypes(reason);
@@ -6920,6 +7300,10 @@
"setAllowedNetworkTypesForReason cannot be called with carrier privileges for"
+ " reason " + reason);
}
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "setAllowedNetworkTypesForReason");
+
if (!TelephonyManager.isValidAllowedNetworkTypesReason(reason)) {
loge("setAllowedNetworkTypesForReason: Invalid allowed network type reason: " + reason);
return false;
@@ -6965,6 +7349,10 @@
@Override
public boolean isTetheringApnRequiredForSubscriber(int subId) {
enforceModifyPermission();
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_DATA, "isTetheringApnRequiredForSubscriber");
+
final long identity = Binder.clearCallingIdentity();
final Phone phone = getPhone(subId);
try {
@@ -7067,6 +7455,9 @@
enforceReadPrivilegedPermission(functionName);
}
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_DATA, "isDataEnabled");
+
final long identity = Binder.clearCallingIdentity();
try {
int phoneId = SubscriptionManager.getPhoneId(subId);
@@ -7113,6 +7504,8 @@
}
}
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_DATA, "isDataEnabledForReason");
final long identity = Binder.clearCallingIdentity();
try {
@@ -7141,6 +7534,9 @@
@Override
public int getCarrierPrivilegeStatus(int subId) {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getCarrierPrivilegeStatus");
+
// No permission needed; this only lets the caller inspect their own status.
return getCarrierPrivilegeStatusForUidWithPermission(subId, Binder.getCallingUid());
}
@@ -7148,6 +7544,10 @@
@Override
public int getCarrierPrivilegeStatusForUid(int subId, int uid) {
enforceReadPrivilegedPermission("getCarrierPrivilegeStatusForUid");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getCarrierPrivilegeStatusForUid");
+
return getCarrierPrivilegeStatusForUidWithPermission(subId, uid);
}
@@ -7168,6 +7568,10 @@
@Override
public int checkCarrierPrivilegesForPackage(int subId, String pkgName) {
enforceReadPrivilegedPermission("checkCarrierPrivilegesForPackage");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "checkCarrierPrivilegesForPackage");
+
if (TextUtils.isEmpty(pkgName)) {
return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
}
@@ -7187,6 +7591,11 @@
@Override
public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) {
enforceReadPrivilegedPermission("checkCarrierPrivilegesForPackageAnyPhone");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
+ "checkCarrierPrivilegesForPackageAnyPhone");
+
return checkCarrierPrivilegesForPackageAnyPhoneWithPermission(pkgName);
}
@@ -7215,6 +7624,11 @@
@Override
public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) {
enforceReadPrivilegedPermission("getCarrierPackageNamesForIntentAndPhone");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
+ "getCarrierPackageNamesForIntentAndPhone");
+
Phone phone = PhoneFactory.getPhone(phoneId);
if (phone == null) {
return Collections.emptyList();
@@ -7243,6 +7657,11 @@
@Override
public List<String> getPackagesWithCarrierPrivilegesForAllPhones() {
enforceReadPrivilegedPermission("getPackagesWithCarrierPrivilegesForAllPhones");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
+ "getPackagesWithCarrierPrivilegesForAllPhones");
+
Set<String> privilegedPackages = new ArraySet<>();
final long identity = Binder.clearCallingIdentity();
try {
@@ -7259,6 +7678,10 @@
public @Nullable String getCarrierServicePackageNameForLogicalSlot(int logicalSlotIndex) {
enforceReadPrivilegedPermission("getCarrierServicePackageNameForLogicalSlot");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
+ "getCarrierServicePackageNameForLogicalSlot");
+
final Phone phone = PhoneFactory.getPhone(logicalSlotIndex);
if (phone == null) {
return null;
@@ -7287,6 +7710,9 @@
public void setCallComposerStatus(int subId, int status) {
enforceModifyPermission();
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CALLING, "setCallComposerStatus");
+
final long identity = Binder.clearCallingIdentity();
try {
Phone phone = getPhone(subId);
@@ -7310,6 +7736,9 @@
public int getCallComposerStatus(int subId) {
enforceReadPrivilegedPermission("getCallComposerStatus");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CALLING, "getCallComposerStatus");
+
final long identity = Binder.clearCallingIdentity();
try {
Phone phone = getPhone(subId);
@@ -7332,6 +7761,10 @@
TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
subId, "setLine1NumberForDisplayForSubscriber");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
+ "setLine1NumberForDisplayForSubscriber");
+
final long identity = Binder.clearCallingIdentity();
try {
final String iccId = getIccId(subId);
@@ -7388,6 +7821,9 @@
return null;
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getLine1NumberForDisplay");
+
final long identity = Binder.clearCallingIdentity();
try {
String iccId = getIccId(subId);
@@ -7515,6 +7951,9 @@
public String[] getMergedImsisFromGroup(int subId, String callingPackage) {
enforceReadPrivilegedPermission("getMergedImsisFromGroup");
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getMergedImsisFromGroup");
+
final long identity = Binder.clearCallingIdentity();
try {
final TelephonyManager telephonyManager = mApp.getSystemService(
@@ -7560,6 +7999,9 @@
TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
subId, "setOperatorBrandOverride");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "setOperatorBrandOverride");
+
final long identity = Binder.clearCallingIdentity();
try {
final Phone phone = getPhone(subId);
@@ -7606,6 +8048,9 @@
throw e;
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getRadioAccessFamily");
+
final long identity = Binder.clearCallingIdentity();
try {
raf = ProxyController.getInstance().getRadioAccessFamily(phoneId);
@@ -7626,6 +8071,10 @@
} catch (PackageManager.NameNotFoundException e) {
throw new SecurityException("Invalid package:" + callingPackage);
}
+
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_CALLING, "uploadCallComposerPicture");
+
RoleManager rm = mApp.getSystemService(RoleManager.class);
List<String> dialerRoleHolders = rm.getRoleHolders(RoleManager.ROLE_DIALER);
if (!dialerRoleHolders.contains(callingPackage)) {
@@ -7712,6 +8161,9 @@
final Phone defaultPhone = getDefaultPhone();
enforceModifyPermission();
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_IMS, "enableVideoCalling");
+
final long identity = Binder.clearCallingIdentity();
try {
ImsManager.getInstance(defaultPhone.getContext(),
@@ -7729,6 +8181,9 @@
return false;
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_IMS, "isVideoCallingEnabled");
+
final long identity = Binder.clearCallingIdentity();
try {
// Check the user preference and the system-level IMS setting. Even if the user has
@@ -7754,6 +8209,9 @@
return false;
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_CALLING, "canChangeDtmfToneLength");
+
final long identity = Binder.clearCallingIdentity();
try {
CarrierConfigManager configManager =
@@ -7772,6 +8230,9 @@
return false;
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY, "isWorldPhone");
+
final long identity = Binder.clearCallingIdentity();
try {
CarrierConfigManager configManager =
@@ -7791,6 +8252,9 @@
@Override
public boolean isHearingAidCompatibilitySupported() {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CALLING, "isHearingAidCompatibilitySupported");
+
final long identity = Binder.clearCallingIdentity();
try {
return mApp.getResources().getBoolean(R.bool.hac_enabled);
@@ -7807,6 +8271,9 @@
*/
@Override
public boolean isRttSupported(int subscriptionId) {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_IMS, "isRttSupported");
+
final long identity = Binder.clearCallingIdentity();
final Phone phone = getPhone(subscriptionId);
if (phone == null) {
@@ -7816,8 +8283,9 @@
try {
boolean isCarrierSupported = mApp.getCarrierConfigForSubId(subscriptionId).getBoolean(
CarrierConfigManager.KEY_RTT_SUPPORTED_BOOL);
- boolean isDeviceSupported =
- phone.getContext().getResources().getBoolean(R.bool.config_support_rtt);
+ boolean isDeviceSupported = (phone.getContext().getResources() != null)
+ ? phone.getContext().getResources().getBoolean(R.bool.config_support_rtt)
+ : false;
return isCarrierSupported && isDeviceSupported;
} finally {
Binder.restoreCallingIdentity(identity);
@@ -7832,6 +8300,12 @@
public boolean isRttEnabled(int subscriptionId) {
final long identity = Binder.clearCallingIdentity();
try {
+ if (mFeatureFlags.enforceTelephonyFeatureMappingForPublicApis()) {
+ if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS)) {
+ return false;
+ }
+ }
+
boolean isRttSupported = isRttSupported(subscriptionId);
boolean isUserRttSettingOn = Settings.Secure.getInt(
mApp.getContentResolver(), Settings.Secure.RTT_CALLING_MODE, 0) != 0;
@@ -7921,6 +8395,10 @@
subscriptionId,
"getPhoneAccountHandleForSubscriptionId, " + "subscriptionId: "
+ subscriptionId);
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CALLING, "getPhoneAccountHandleForSubscriptionId");
+
final long identity = Binder.clearCallingIdentity();
try {
Phone phone = getPhone(subscriptionId);
@@ -7988,6 +8466,10 @@
@Override
public void factoryReset(int subId, String callingPackage) {
enforceSettingsPermission();
+
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY, "factoryReset");
+
if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
return;
}
@@ -8060,6 +8542,10 @@
@Override
public String getSimLocaleForSubscriber(int subId) {
enforceReadPrivilegedPermission("getSimLocaleForSubscriber, subId: " + subId);
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getSimLocaleForSubscriber");
+
final Phone phone = getPhone(subId);
if (phone == null) {
log("getSimLocaleForSubscriber, invalid subId");
@@ -8142,6 +8628,10 @@
@Override
public void requestModemActivityInfo(ResultReceiver result) {
enforceModifyPermission();
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY, "requestModemActivityInfo");
+
WorkSource workSource = getWorkSource(Binder.getCallingUid());
final long identity = Binder.clearCallingIdentity();
@@ -8286,6 +8776,9 @@
return null;
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getServiceStateForSubscriber");
+
boolean hasFinePermission = false;
boolean hasCoarsePermission = false;
if (!renounceFineLocationAccess) {
@@ -8365,6 +8858,9 @@
*/
@Override
public Uri getVoicemailRingtoneUri(PhoneAccountHandle accountHandle) {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CALLING, "getVoicemailRingtoneUri");
+
final long identity = Binder.clearCallingIdentity();
try {
Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
@@ -8401,6 +8897,9 @@
"setVoicemailRingtoneUri");
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_CALLING, "setVoicemailRingtoneUri");
+
final long identity = Binder.clearCallingIdentity();
try {
Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
@@ -8422,6 +8921,9 @@
*/
@Override
public boolean isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle) {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CALLING, "isVoicemailVibrationEnabled");
+
final long identity = Binder.clearCallingIdentity();
try {
Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
@@ -8458,6 +8960,9 @@
"setVoicemailVibrationEnabled");
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_CALLING, "setVoicemailVibrationEnabled");
+
final long identity = Binder.clearCallingIdentity();
try {
Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
@@ -8534,6 +9039,10 @@
@Override
public String getAidForAppType(int subId, int appType) {
enforceReadPrivilegedPermission("getAidForAppType");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getAidForAppType");
+
Phone phone = getPhone(subId);
final long identity = Binder.clearCallingIdentity();
@@ -8591,6 +9100,10 @@
@Override
public String getCdmaPrlVersion(int subId) {
enforceReadPrivilegedPermission("getCdmaPrlVersion");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CDMA, "getCdmaPrlVersion");
+
Phone phone = getPhone(subId);
final long identity = Binder.clearCallingIdentity();
@@ -8640,6 +9153,10 @@
@TelephonyManager.SetCarrierRestrictionResult
public int setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules) {
enforceModifyPermission();
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CARRIERLOCK, "setAllowedCarriers");
+
WorkSource workSource = getWorkSource(Binder.getCallingUid());
if (carrierRestrictionRules == null) {
@@ -8666,6 +9183,10 @@
@Override
public CarrierRestrictionRules getAllowedCarriers() {
enforceReadPrivilegedPermission("getAllowedCarriers");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CARRIERLOCK, "getAllowedCarriers");
+
WorkSource workSource = getWorkSource(Binder.getCallingUid());
final long identity = Binder.clearCallingIdentity();
@@ -8696,6 +9217,10 @@
@Override
public void getCarrierRestrictionStatus(IIntegerConsumer callback, String packageName) {
enforceReadPermission("getCarrierRestrictionStatus");
+
+ enforceTelephonyFeatureWithException(packageName,
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getCarrierRestrictionStatus");
+
int carrierId = validateCallerAndGetCarrierId(packageName);
if (carrierId == CarrierAllowListInfo.INVALID_CARRIER_ID) {
Rlog.e(LOG_TAG, "getCarrierRestrictionStatus: caller is not registered");
@@ -8818,6 +9343,11 @@
@Override
public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
enforceModifyPermission();
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS,
+ "carrierActionReportDefaultNetworkStatus");
+
final Phone phone = getPhone(subId);
final long identity = Binder.clearCallingIdentity();
@@ -8842,6 +9372,10 @@
@Override
public void carrierActionResetAll(int subId) {
enforceModifyPermission();
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "carrierActionResetAll");
+
final Phone phone = getPhone(subId);
if (phone == null) {
loge("carrierAction: ResetAll fails with invalid sibId: " + subId);
@@ -8910,6 +9444,9 @@
callingPackage, null, null);
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_DATA, "setDataEnabledForReason");
+
final long identity = Binder.clearCallingIdentity();
try {
Phone phone = getPhone(subId);
@@ -8980,6 +9517,10 @@
@Override
public void setSimPowerStateForSlot(int slotIndex, int state) {
enforceModifyPermission();
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "setSimPowerStateForSlot");
+
Phone phone = PhoneFactory.getPhone(slotIndex);
WorkSource workSource = getWorkSource(Binder.getCallingUid());
@@ -9009,6 +9550,11 @@
public void setSimPowerStateForSlotWithCallback(int slotIndex, int state,
IIntegerConsumer callback) {
enforceModifyPermission();
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
+ "setSimPowerStateForSlotWithCallback");
+
Phone phone = PhoneFactory.getPhone(slotIndex);
WorkSource workSource = getWorkSource(Binder.getCallingUid());
@@ -9046,6 +9592,10 @@
@Override
public boolean getEmergencyCallbackMode(int subId) {
enforceReadPrivilegedPermission("getEmergencyCallbackMode");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CALLING, "getEmergencyCallbackMode");
+
final long identity = Binder.clearCallingIdentity();
try {
return getPhoneFromSubIdOrDefault(subId).isInEcm();
@@ -9063,6 +9613,9 @@
*/
@Override
public SignalStrength getSignalStrength(int subId) {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getSignalStrength");
+
final long identity = Binder.clearCallingIdentity();
try {
Phone p = getPhone(subId);
@@ -9092,6 +9645,9 @@
return TelephonyManager.RADIO_POWER_UNAVAILABLE;
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getRadioPowerState");
+
final long identity = Binder.clearCallingIdentity();
try {
return phone.getRadioPowerState();
@@ -9132,6 +9688,9 @@
mApp, subId, functionName);
}
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_DATA, "isDataRoamingEnabled");
+
boolean isEnabled = false;
final long identity = Binder.clearCallingIdentity();
try {
@@ -9159,6 +9718,9 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mApp, subId, "setDataRoamingEnabled");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_DATA, "setDataRoamingEnabled");
+
final long identity = Binder.clearCallingIdentity();
try {
Phone phone = getPhone(subId);
@@ -9176,6 +9738,9 @@
.enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
mApp, subId, "isManualNetworkSelectionAllowed");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "isManualNetworkSelectionAllowed");
+
boolean isAllowed = true;
final long identity = Binder.clearCallingIdentity();
try {
@@ -9222,6 +9787,10 @@
throw new SecurityException("Caller does not have permission.");
}
}
+
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getUiccCardsInfo");
+
// checking compatibility, if calling app's target SDK is T and beyond.
if (CompatChanges.isChangeEnabled(GET_API_SIGNATURES_FROM_UICC_PORT_INFO,
Binder.getCallingUid())) {
@@ -9332,6 +9901,9 @@
// we are reading iccId which is PII data.
enforceReadPrivilegedPermission("getUiccSlotsInfo");
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getUiccSlotsInfo");
+
// checking compatibility, if calling app's target SDK is T and beyond.
if (CompatChanges.isChangeEnabled(GET_API_SIGNATURES_FROM_UICC_PORT_INFO,
Binder.getCallingUid())) {
@@ -9434,6 +10006,9 @@
public boolean switchSlots(int[] physicalSlots) {
enforceModifyPermission();
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "switchSlots");
+
final long identity = Binder.clearCallingIdentity();
try {
List<UiccSlotMapping> slotMappings = new ArrayList<>();
@@ -9453,6 +10028,9 @@
public boolean setSimSlotMapping(@NonNull List<UiccSlotMapping> slotMapping) {
enforceModifyPermission();
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "setSimSlotMapping");
+
final long identity = Binder.clearCallingIdentity();
try {
return (Boolean) sendRequest(CMD_SWITCH_SLOTS, slotMapping);
@@ -9463,6 +10041,9 @@
@Override
public int getCardIdForDefaultEuicc(int subId, String callingPackage) {
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_EUICC, "getCardIdForDefaultEuicc");
+
final long identity = Binder.clearCallingIdentity();
try {
return UiccController.getInstance().getCardIdForDefaultEuicc();
@@ -9629,6 +10210,9 @@
.enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
mApp, subId, "getCdmaRoamingMode");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CDMA, "getCdmaRoamingMode");
+
final long identity = Binder.clearCallingIdentity();
try {
return (int) sendRequest(CMD_GET_CDMA_ROAMING_MODE, null /* argument */, subId);
@@ -9642,6 +10226,9 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mApp, subId, "setCdmaRoamingMode");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CDMA, "setCdmaRoamingMode");
+
final long identity = Binder.clearCallingIdentity();
try {
return (boolean) sendRequest(CMD_SET_CDMA_ROAMING_MODE, mode, subId);
@@ -9656,6 +10243,9 @@
.enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
mApp, subId, "getCdmaSubscriptionMode");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CDMA, "getCdmaSubscriptionMode");
+
final long identity = Binder.clearCallingIdentity();
try {
return (int) sendRequest(CMD_GET_CDMA_SUBSCRIPTION_MODE, null /* argument */, subId);
@@ -9669,6 +10259,9 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mApp, subId, "setCdmaSubscriptionMode");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CDMA, "setCdmaSubscriptionMode");
+
final long identity = Binder.clearCallingIdentity();
try {
return (boolean) sendRequest(CMD_SET_CDMA_SUBSCRIPTION_MODE, mode, subId);
@@ -9685,6 +10278,10 @@
"getEmergencyNumberList")) {
throw new SecurityException("Requires READ_PHONE_STATE permission.");
}
+
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_CALLING, "getEmergencyNumberList");
+
final long identity = Binder.clearCallingIdentity();
try {
Map<Integer, List<EmergencyNumber>> emergencyNumberListInternal = new HashMap<>();
@@ -9710,6 +10307,10 @@
.enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
mApp, defaultPhone.getSubId(), "isEmergencyNumber(Potential)");
}
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CALLING, "isEmergencyNumber");
+
final long identity = Binder.clearCallingIdentity();
try {
for (Phone phone: PhoneFactory.getPhones()) {
@@ -9802,6 +10403,9 @@
public int getEmergencyNumberDbVersion(int subId) {
enforceReadPrivilegedPermission("getEmergencyNumberDbVersion");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CALLING, "getEmergencyNumberDbVersion");
+
final long identity = Binder.clearCallingIdentity();
try {
final Phone phone = getPhone(subId);
@@ -9819,6 +10423,9 @@
public void notifyOtaEmergencyNumberDbInstalled() {
enforceModifyPermission();
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CALLING, "notifyOtaEmergencyNumberDbInstalled");
+
final long identity = Binder.clearCallingIdentity();
try {
for (Phone phone: PhoneFactory.getPhones()) {
@@ -9836,6 +10443,9 @@
public void updateOtaEmergencyNumberDbFilePath(ParcelFileDescriptor otaParcelFileDescriptor) {
enforceActiveEmergencySessionPermission();
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CALLING, "updateOtaEmergencyNumberDbFilePath");
+
final long identity = Binder.clearCallingIdentity();
try {
for (Phone phone: PhoneFactory.getPhones()) {
@@ -9853,6 +10463,9 @@
public void resetOtaEmergencyNumberDbFilePath() {
enforceActiveEmergencySessionPermission();
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CALLING, "resetOtaEmergencyNumberDbFilePath");
+
final long identity = Binder.clearCallingIdentity();
try {
for (Phone phone: PhoneFactory.getPhones()) {
@@ -9893,6 +10506,9 @@
public boolean enableModemForSlot(int slotIndex, boolean enable) {
enforceModifyPermission();
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY, "enableModemForSlot");
+
final long identity = Binder.clearCallingIdentity();
try {
Phone phone = PhoneFactory.getPhone(slotIndex);
@@ -9921,6 +10537,9 @@
throw new SecurityException("Requires READ_PHONE_STATE permission.");
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY, "isModemEnabledForSlot");
+
final long identity = Binder.clearCallingIdentity();
try {
try {
@@ -9937,6 +10556,9 @@
public void setMultiSimCarrierRestriction(boolean isMultiSimCarrierRestricted) {
enforceModifyPermission();
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_CARRIERLOCK, "setMultiSimCarrierRestriction");
+
final long identity = Binder.clearCallingIdentity();
try {
mTelephonySharedPreferences.edit()
@@ -9956,6 +10578,9 @@
return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "isMultiSimSupported");
+
final long identity = Binder.clearCallingIdentity();
try {
return isMultiSimSupportedInternal();
@@ -10007,6 +10632,10 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mApp, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, "switchMultiSimConfig");
}
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "switchMultiSimConfig");
+
final long identity = Binder.clearCallingIdentity();
try {
@@ -10024,6 +10653,10 @@
@Override
public boolean isApplicationOnUicc(int subId, int appType) {
enforceReadPrivilegedPermission("isApplicationOnUicc");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "isApplicationOnUicc");
+
Phone phone = getPhone(subId);
if (phone == null) {
return false;
@@ -10060,6 +10693,11 @@
"doesSwitchMultiSimConfigTriggerReboot")) {
return false;
}
+
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
+ "doesSwitchMultiSimConfigTriggerReboot");
+
final long identity = Binder.clearCallingIdentity();
try {
return mPhoneConfigurationManager.isRebootRequiredForModemConfigChange();
@@ -10080,6 +10718,10 @@
// Verify that the callingPackage belongs to the calling UID
mApp.getSystemService(AppOpsManager.class)
.checkPackage(Binder.getCallingUid(), callingPackage);
+
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getSlotsMapping");
+
final long identity = Binder.clearCallingIdentity();
List<UiccSlotMapping> slotMap = new ArrayList<>();
try {
@@ -10150,6 +10792,9 @@
enforceReadPrivilegedPermission("Needs READ_PRIVILEGED_PHONE_STATE for "
+ "isDataEnabledForApn");
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_DATA, "isDataEnabledForApn");
+
// Now that all security checks passes, perform the operation as ourselves.
final long identity = Binder.clearCallingIdentity();
try {
@@ -10172,6 +10817,9 @@
public boolean isApnMetered(@ApnType int apnType, int subId) {
enforceReadPrivilegedPermission("isApnMetered");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_DATA, "isApnMetered");
+
// Now that all security checks passes, perform the operation as ourselves.
final long identity = Binder.clearCallingIdentity();
try {
@@ -10189,6 +10837,10 @@
public void setSystemSelectionChannels(List<RadioAccessSpecifier> specifiers,
int subscriptionId, IBooleanConsumer resultCallback) {
enforceModifyPermission();
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "setSystemSelectionChannels");
+
long token = Binder.clearCallingIdentity();
try {
Phone phone = getPhone(subscriptionId);
@@ -10223,6 +10875,10 @@
TelephonyPermissions
.enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
mApp, subId, "getSystemSelectionChannels");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getSystemSelectionChannels");
+
WorkSource workSource = getWorkSource(Binder.getCallingUid());
final long identity = Binder.clearCallingIdentity();
try {
@@ -10241,6 +10897,10 @@
@Override
public boolean isMvnoMatched(int slotIndex, int mvnoType, @NonNull String mvnoMatchData) {
enforceReadPrivilegedPermission("isMvnoMatched");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "isMvnoMatched");
+
return UiccController.getInstance().mvnoMatches(slotIndex, mvnoType, mvnoMatchData);
}
@@ -10288,6 +10948,9 @@
@Override
public String getMmsUAProfUrl(int subId) {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_MESSAGING, "getMmsUAProfUrl");
+
//TODO investigate if this API should require proper permission check in R b/133791609
final long identity = Binder.clearCallingIdentity();
try {
@@ -10305,6 +10968,9 @@
@Override
public String getMmsUserAgent(int subId) {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_MESSAGING, "getMmsUserAgent");
+
//TODO investigate if this API should require proper permission check in R b/133791609
final long identity = Binder.clearCallingIdentity();
try {
@@ -10324,6 +10990,9 @@
public boolean isMobileDataPolicyEnabled(int subscriptionId, int policy) {
enforceReadPrivilegedPermission("isMobileDataPolicyEnabled");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_DATA, "isMobileDataPolicyEnabled");
+
final long identity = Binder.clearCallingIdentity();
try {
Phone phone = getPhone(subscriptionId);
@@ -10340,6 +11009,9 @@
boolean enabled) {
enforceModifyPermission();
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_DATA, "setMobileDataPolicyEnabled");
+
final long identity = Binder.clearCallingIdentity();
try {
Phone phone = getPhone(subscriptionId);
@@ -10394,10 +11066,19 @@
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
}
- if (!isImsAvailableOnDevice()) {
- // ProvisioningManager can not handle ServiceSpecificException.
- // Throw the IllegalStateException and annotate ProvisioningManager.
- throw new IllegalStateException("IMS not available on device.");
+
+ if (!mFeatureFlags.enforceTelephonyFeatureMappingForPublicApis()
+ || !CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, getCurrentPackageName(),
+ Binder.getCallingUserHandle())) {
+ if (!isImsAvailableOnDevice()) {
+ // ProvisioningManager can not handle ServiceSpecificException.
+ // Throw the IllegalStateException and annotate ProvisioningManager.
+ throw new IllegalStateException("IMS not available on device.");
+ }
+ } else {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION,
+ "notifyRcsAutoConfigurationReceived");
}
final long identity = Binder.clearCallingIdentity();
@@ -10412,6 +11093,9 @@
public boolean isIccLockEnabled(int subId) {
enforceReadPrivilegedPermission("isIccLockEnabled");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "isIccLockEnabled");
+
// Now that all security checks passes, perform the operation as ourselves.
final long identity = Binder.clearCallingIdentity();
try {
@@ -10441,6 +11125,9 @@
public int setIccLockEnabled(int subId, boolean enabled, String password) {
enforceModifyPermission();
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "setIccLockEnabled");
+
Phone phone = getPhone(subId);
if (phone == null) {
return 0;
@@ -10473,6 +11160,9 @@
public int changeIccLockPassword(int subId, String oldPassword, String newPassword) {
enforceModifyPermission();
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "changeIccLockPassword");
+
Phone phone = getPhone(subId);
if (phone == null) {
return 0;
@@ -10543,6 +11233,9 @@
throw new SecurityException("Requires READ_PHONE_STATE permission.");
}
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getEquivalentHomePlmns");
+
Phone phone = getPhone(subId);
if (phone == null) {
throw new RuntimeException("phone is not available");
@@ -10559,6 +11252,10 @@
@Override
public boolean isRadioInterfaceCapabilitySupported(
final @NonNull @TelephonyManager.RadioInterfaceCapability String capability) {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS,
+ "isRadioInterfaceCapabilitySupported");
+
Set<String> radioInterfaceCapabilities =
mRadioInterfaceCapabilities.getCapabilities();
if (radioInterfaceCapabilities == null) {
@@ -10575,6 +11272,10 @@
Binder.getCallingUid(), "bootstrapAuthenticationRequest",
Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION,
Manifest.permission.MODIFY_PHONE_STATE);
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "bootstrapAuthenticationRequest");
+
if (DBG) {
log("bootstrapAuthenticationRequest, subId:" + subId + ", appType:"
+ appType + ", NAF:" + nafUrl + ", sp:" + securityProtocol
@@ -10734,6 +11435,10 @@
enforceModifyPermission();
mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
+
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "sendThermalMitigationRequest");
+
if (!getThermalMitigationAllowlist(getDefaultPhone().getContext())
.contains(callingPackage)) {
throw new SecurityException("Calling package must be configured in the device config. "
@@ -10964,9 +11669,16 @@
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
}
- if (!isImsAvailableOnDevice()) {
- throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
- "IMS not available on device.");
+ if (!mFeatureFlags.enforceTelephonyFeatureMappingForPublicApis()
+ || !CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, getCurrentPackageName(),
+ Binder.getCallingUserHandle())) {
+ if (!isImsAvailableOnDevice()) {
+ throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
+ "IMS not available on device.");
+ }
+ } else {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION, "registerRcsProvisioningCallback");
}
final long identity = Binder.clearCallingIdentity();
@@ -10995,10 +11707,19 @@
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
}
- if (!isImsAvailableOnDevice()) {
- // operation failed silently
- Rlog.w(LOG_TAG, "IMS not available on device.");
- return;
+
+ if (!mFeatureFlags.enforceTelephonyFeatureMappingForPublicApis()
+ || !CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, getCurrentPackageName(),
+ Binder.getCallingUserHandle())) {
+ if (!isImsAvailableOnDevice()) {
+ // operation failed silently
+ Rlog.w(LOG_TAG, "IMS not available on device.");
+ return;
+ }
+ } else {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION,
+ "unregisterRcsProvisioningCallback");
}
final long identity = Binder.clearCallingIdentity();
@@ -11021,10 +11742,17 @@
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
}
- if (!isImsAvailableOnDevice()) {
- // ProvisioningManager can not handle ServiceSpecificException.
- // Throw the IllegalStateException and annotate ProvisioningManager.
- throw new IllegalStateException("IMS not available on device.");
+ if (!mFeatureFlags.enforceTelephonyFeatureMappingForPublicApis()
+ || !CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, getCurrentPackageName(),
+ Binder.getCallingUserHandle())) {
+ if (!isImsAvailableOnDevice()) {
+ // ProvisioningManager can not handle ServiceSpecificException.
+ // Throw the IllegalStateException and annotate ProvisioningManager.
+ throw new IllegalStateException("IMS not available on device.");
+ }
+ } else {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION, "triggerRcsReconfiguration");
}
final long identity = Binder.clearCallingIdentity();
@@ -11046,9 +11774,16 @@
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
}
- if (!isImsAvailableOnDevice()) {
- throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
- "IMS not available on device.");
+ if (!mFeatureFlags.enforceTelephonyFeatureMappingForPublicApis()
+ || !CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, getCurrentPackageName(),
+ Binder.getCallingUserHandle())) {
+ if (!isImsAvailableOnDevice()) {
+ throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
+ "IMS not available on device.");
+ }
+ } else {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION, "setRcsClientConfiguration");
}
final long identity = Binder.clearCallingIdentity();
@@ -11462,6 +12197,9 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mApp, subId, "setSignalStrengthUpdateRequest");
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "setSignalStrengthUpdateRequest");
+
final int callingUid = Binder.getCallingUid();
// Verify that tha callingPackage belongs to the calling UID
mApp.getSystemService(AppOpsManager.class)
@@ -11488,6 +12226,9 @@
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
mApp, subId, "clearSignalStrengthUpdateRequest");
+ enforceTelephonyFeatureWithException(callingPackage,
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "clearSignalStrengthUpdateRequest");
+
final int callingUid = Binder.getCallingUid();
// Verify that tha callingPackage belongs to the calling UID
mApp.getSystemService(AppOpsManager.class)
@@ -11554,6 +12295,10 @@
@Override
public PhoneCapability getPhoneCapability() {
enforceReadPrivilegedPermission("getPhoneCapability");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY, "getPhoneCapability");
+
final long identity = Binder.clearCallingIdentity();
try {
return mPhoneConfigurationManager.getCurrentPhoneCapability();
@@ -11572,6 +12317,9 @@
WorkSource workSource = getWorkSource(Binder.getCallingUid());
enforceRebootPermission();
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "prepareForUnattendedReboot");
+
final long identity = Binder.clearCallingIdentity();
try {
return (int) sendRequest(CMD_PREPARE_UNATTENDED_REBOOT, null, workSource);
@@ -11592,6 +12340,10 @@
.enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, "getSlicingConfig");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS,
+ "getSlicingConfig");
+
final long identity = Binder.clearCallingIdentity();
try {
Phone phone = getDefaultPhone();
@@ -11620,6 +12372,9 @@
+ "permission READ_BASIC_PHONE_STATE.");
}
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_DATA, "isPremiumCapabilityAvailableForPurchase");
+
Phone phone = getPhone(subId);
if (phone == null) {
loge("isPremiumCapabilityAvailableForPurchase: phone is null, subId=" + subId);
@@ -11662,6 +12417,9 @@
throw new SecurityException("purchasePremiumCapability requires permission INTERNET.");
}
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_DATA, "purchasePremiumCapability");
+
Phone phone = getPhone(subId);
if (phone == null) {
try {
@@ -11942,6 +12700,10 @@
boolean updateIfNeeded) {
enforceInteractAcrossUsersPermission("getDefaultRespondViaMessageApplication");
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_MESSAGING,
+ "getDefaultRespondViaMessageApplication");
+
Context context = getPhoneFromSubIdOrDefault(subId).getContext();
UserHandle userHandle = null;
@@ -12031,6 +12793,9 @@
@Override
@SimState
public int getSimStateForSlotIndex(int slotIndex) {
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getSimStateForSlotIndex");
+
IccCardConstants.State simState;
if (slotIndex < 0) {
simState = IccCardConstants.State.UNKNOWN;
@@ -12106,6 +12871,10 @@
public List<CellBroadcastIdRange> getCellBroadcastIdRanges(int subId) {
mApp.enforceCallingPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS,
"getCellBroadcastIdRanges");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_MESSAGING, "getCellBroadcastIdRanges");
+
final long identity = Binder.clearCallingIdentity();
try {
return getPhone(subId).getCellBroadcastIdRanges();
@@ -12125,6 +12894,10 @@
@Nullable IIntegerConsumer callback) {
mApp.enforceCallingPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS,
"setCellBroadcastIdRanges");
+
+ enforceTelephonyFeatureWithException(getCurrentPackageName(),
+ PackageManager.FEATURE_TELEPHONY_MESSAGING, "setCellBroadcastIdRanges");
+
final long identity = Binder.clearCallingIdentity();
try {
Phone phone = getPhoneFromSubId(subId);
@@ -12951,4 +13724,47 @@
return mCarrierId;
}
}
+
+ /*
+ * PhoneInterfaceManager is a singleton. Unit test calls the init() with context.
+ * But the context that is passed in is unused if the phone app is already alive.
+ * In this case PackageManager object is different in PhoneInterfaceManager and Unit test.
+ */
+ @VisibleForTesting
+ public void setPackageManager(PackageManager packageManager) {
+ mPackageManager = packageManager;
+ }
+
+ /*
+ * PhoneInterfaceManager is a singleton. Unit test calls the init() with FeatureFlags.
+ * But the FeatureFlags that is passed in is unused if the phone app is already alive.
+ * In this case FeatureFlags object is different in PhoneInterfaceManager and Unit test.
+ */
+ @VisibleForTesting
+ public void setFeatureFlags(FeatureFlags featureFlags) {
+ mFeatureFlags = featureFlags;
+ }
+
+ /**
+ * Make sure the device has required telephony feature
+ *
+ * @throws UnsupportedOperationException if the device does not have required telephony feature
+ */
+ private void enforceTelephonyFeatureWithException(@Nullable String callingPackage,
+ @NonNull String telephonyFeature, @NonNull String methodName) {
+ if (callingPackage == null || mPackageManager == null) {
+ return;
+ }
+
+ if (!mFeatureFlags.enforceTelephonyFeatureMappingForPublicApis()
+ || !CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, callingPackage,
+ Binder.getCallingUserHandle())) {
+ return;
+ }
+
+ if (!mPackageManager.hasSystemFeature(telephonyFeature)) {
+ throw new UnsupportedOperationException(
+ methodName + " is unsupported without " + telephonyFeature);
+ }
+ }
}
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/CarrierConfigLoaderTest.java b/tests/src/com/android/phone/CarrierConfigLoaderTest.java
index bd2e4f7..f4197d9 100644
--- a/tests/src/com/android/phone/CarrierConfigLoaderTest.java
+++ b/tests/src/com/android/phone/CarrierConfigLoaderTest.java
@@ -21,6 +21,7 @@
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
@@ -30,6 +31,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.compat.testing.PlatformCompatChangeRule;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
@@ -56,12 +58,17 @@
import com.android.TelephonyTestBase;
import com.android.internal.telephony.IccCardConstants;
+import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
+import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
@@ -76,10 +83,14 @@
*/
@RunWith(AndroidJUnit4.class)
public class CarrierConfigLoaderTest extends TelephonyTestBase {
+ @Rule
+ public TestRule compatChangeRule = new PlatformCompatChangeRule();
+ private static final String TAG = CarrierConfigLoaderTest.class.getSimpleName();
private static final int DEFAULT_PHONE_ID = 0;
private static final int DEFAULT_SUB_ID = SubscriptionManager.getDefaultSubscriptionId();
private static final String PLATFORM_CARRIER_CONFIG_PACKAGE = "com.android.carrierconfig";
+ private static final String PLATFORM_CARRIER_CONFIG_FEATURE = "com.android.carrierconfig";
private static final long PLATFORM_CARRIER_CONFIG_PACKAGE_VERSION_CODE = 1;
private static final String CARRIER_CONFIG_EXAMPLE_KEY =
CarrierConfigManager.KEY_CARRIER_USSD_METHOD_INT;
@@ -92,6 +103,7 @@
@Mock SubscriptionManagerService mSubscriptionManagerService;
@Mock SharedPreferences mSharedPreferences;
@Mock TelephonyRegistryManager mTelephonyRegistryManager;
+ @Mock FeatureFlags mFeatureFlags;
private TelephonyManager mTelephonyManager;
private CarrierConfigLoader mCarrierConfigLoader;
@@ -118,6 +130,8 @@
doReturn(Build.FINGERPRINT).when(mSharedPreferences).getString(eq("build_fingerprint"),
any());
doReturn(mPackageManager).when(mContext).getPackageManager();
+ doReturn(new String[]{TAG}).when(mPackageManager).getPackagesForUid(anyInt());
+
doReturn(mResources).when(mContext).getResources();
doReturn(InstrumentationRegistry.getTargetContext().getFilesDir()).when(
mContext).getFilesDir();
@@ -141,7 +155,8 @@
mHandlerThread.start();
mTestableLooper = new TestableLooper(mHandlerThread.getLooper());
- mCarrierConfigLoader = new CarrierConfigLoader(mContext, mTestableLooper.getLooper());
+ mCarrierConfigLoader = new CarrierConfigLoader(mContext, mTestableLooper.getLooper(),
+ mFeatureFlags);
mHandler = mCarrierConfigLoader.getHandler();
// Clear all configs to have the same starting point.
@@ -412,6 +427,34 @@
assertThat(dumpContent).doesNotContain("Permission Denial:");
}
+ @Test
+ @EnableCompatChanges({TelephonyManager.ENABLE_FEATURE_MAPPING})
+ public void testGetConfigForSubIdWithFeature_withTelephonyFeatureMapping() {
+ doNothing().when(mContext).enforcePermission(
+ eq(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE),
+ anyInt(), anyInt(), anyString());
+
+ doReturn(true).when(mFeatureFlags).enforceTelephonyFeatureMappingForPublicApis();
+ doReturn(false).when(mPackageManager).hasSystemFeature(
+ eq(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION));
+
+ // Not defined required feature, expect UnsupportedOperationException
+ assertThrows(UnsupportedOperationException.class,
+ () -> mCarrierConfigLoader.getConfigForSubIdWithFeature(DEFAULT_SUB_ID,
+ PLATFORM_CARRIER_CONFIG_PACKAGE, PLATFORM_CARRIER_CONFIG_FEATURE));
+
+ doReturn(true).when(mPackageManager).hasSystemFeature(
+ eq(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION));
+
+ // Defined required feature, not expect UnsupportedOperationException
+ try {
+ mCarrierConfigLoader.getConfigForSubIdWithFeature(DEFAULT_SUB_ID,
+ PLATFORM_CARRIER_CONFIG_PACKAGE, PLATFORM_CARRIER_CONFIG_FEATURE);
+ } catch (UnsupportedOperationException e) {
+ fail("not expected UnsupportedOperationException");
+ }
+ }
+
private static PersistableBundle getTestConfig() {
PersistableBundle config = new PersistableBundle();
config.putInt(CARRIER_CONFIG_EXAMPLE_KEY, CARRIER_CONFIG_EXAMPLE_VALUE);
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));
+ }
}