diff options
| -rw-r--r-- | core/api/current.txt | 21 | ||||
| -rw-r--r-- | telephony/java/android/telephony/CarrierConfigManager.java | 78 | ||||
| -rw-r--r-- | telephony/java/android/telephony/TelephonyManager.java | 260 | ||||
| -rw-r--r-- | telephony/java/com/android/internal/telephony/ITelephony.aidl | 10 |
4 files changed, 369 insertions, 0 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 2d5ed18a9599..fdc106c4078a 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -41551,6 +41551,10 @@ package android.telephony { field public static final String KEY_OPPORTUNISTIC_NETWORK_PING_PONG_TIME_LONG = "opportunistic_network_ping_pong_time_long"; field public static final String KEY_PING_TEST_BEFORE_DATA_SWITCH_BOOL = "ping_test_before_data_switch_bool"; field public static final String KEY_PREFER_2G_BOOL = "prefer_2g_bool"; + field public static final String KEY_PREMIUM_CAPABILITY_NOTIFICATION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG = "premium_capability_notification_backoff_hysteresis_time_millis_long"; + field public static final String KEY_PREMIUM_CAPABILITY_NOTIFICATION_DISPLAY_TIMEOUT_MILLIS_LONG = "premium_capability_notification_display_timeout_millis_long"; + field public static final String KEY_PREMIUM_CAPABILITY_PURCHASE_CONDITION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG = "premium_capability_purchase_condition_backoff_hysteresis_time_millis_long"; + field public static final String KEY_PREMIUM_CAPABILITY_PURCHASE_URL_STRING = "premium_capability_purchase_url_string"; field public static final String KEY_PREVENT_CLIR_ACTIVATION_AND_DEACTIVATION_CODE_BOOL = "prevent_clir_activation_and_deactivation_code_bool"; field public static final String KEY_RADIO_RESTART_FAILURE_CAUSES_INT_ARRAY = "radio_restart_failure_causes_int_array"; field public static final String KEY_RCS_CONFIG_SERVER_URL_STRING = "rcs_config_server_url_string"; @@ -41583,6 +41587,7 @@ package android.telephony { field public static final String KEY_SMDP_SERVER_ADDRESS_STRING = "smdp_server_address_string"; field public static final String KEY_SMS_REQUIRES_DESTINATION_NUMBER_CONVERSION_BOOL = "sms_requires_destination_number_conversion_bool"; field public static final String KEY_SUBSCRIPTION_GROUP_UUID_STRING = "subscription_group_uuid_string"; + field public static final String KEY_SUPPORTED_PREMIUM_CAPABILITIES_INT_ARRAY = "supported_premium_capabilities_int_array"; field public static final String KEY_SUPPORTS_CALL_COMPOSER_BOOL = "supports_call_composer_bool"; field public static final String KEY_SUPPORTS_DEVICE_TO_DEVICE_COMMUNICATION_USING_DTMF_BOOL = "supports_device_to_device_communication_using_dtmf_bool"; field public static final String KEY_SUPPORTS_DEVICE_TO_DEVICE_COMMUNICATION_USING_RTP_BOOL = "supports_device_to_device_communication_using_rtp_bool"; @@ -43646,6 +43651,7 @@ package android.telephony { method @RequiresPermission(anyOf={android.Manifest.permission.READ_PHONE_STATE, "android.permission.READ_PRIVILEGED_PHONE_STATE"}) public boolean isModemEnabledForSlot(int); method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int isMultiSimSupported(); method public boolean isNetworkRoaming(); + method @RequiresPermission(android.Manifest.permission.READ_BASIC_PHONE_STATE) public boolean isPremiumCapabilityAvailableForPurchase(int); method public boolean isRadioInterfaceCapabilitySupported(@NonNull String); method public boolean isRttSupported(); method public boolean isSmsCapable(); @@ -43654,6 +43660,7 @@ package android.telephony { method public boolean isVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle); method public boolean isWorldPhone(); method @Deprecated public void listen(android.telephony.PhoneStateListener, int); + method @RequiresPermission(android.Manifest.permission.READ_BASIC_PHONE_STATE) public void purchasePremiumCapability(int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void rebootModem(); method public void registerTelephonyCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyCallback); method public void registerTelephonyCallback(int, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyCallback); @@ -43823,6 +43830,20 @@ package android.telephony { field public static final int PHONE_TYPE_GSM = 1; // 0x1 field public static final int PHONE_TYPE_NONE = 0; // 0x0 field public static final int PHONE_TYPE_SIP = 3; // 0x3 + field public static final int PREMIUM_CAPABILITY_REALTIME_INTERACTIVE_TRAFFIC = 1; // 0x1 + field public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_ALREADY_IN_PROGRESS = 4; // 0x4 + field public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_ALREADY_PURCHASED = 3; // 0x3 + field public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_CARRIER_DISABLED = 7; // 0x7 + field public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_CARRIER_ERROR = 8; // 0x8 + field public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_FEATURE_NOT_SUPPORTED = 10; // 0xa + field public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_NETWORK_CONGESTED = 13; // 0xd + field public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_NETWORK_NOT_AVAILABLE = 12; // 0xc + field public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_REQUEST_FAILED = 11; // 0xb + field public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_SUCCESS = 1; // 0x1 + field public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_THROTTLED = 2; // 0x2 + field public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_TIMEOUT = 9; // 0x9 + field public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_CANCELED = 6; // 0x6 + field public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_DISABLED = 5; // 0x5 field public static final int SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION = 2; // 0x2 field public static final int SET_OPPORTUNISTIC_SUB_NO_OPPORTUNISTIC_SUB_AVAILABLE = 3; // 0x3 field public static final int SET_OPPORTUNISTIC_SUB_REMOTE_SERVICE_EXCEPTION = 4; // 0x4 diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index b6944eb17b0c..2a1efed63dd2 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -52,7 +52,9 @@ import com.android.internal.telephony.ICarrierConfigLoader; import com.android.telephony.Rlog; import java.util.List; +import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; /** * Provides access to telephony configuration values that are carrier-specific. @@ -8647,6 +8649,73 @@ public class CarrierConfigManager { "unthrottle_data_retry_when_tac_changes_bool"; /** + * A list of premium capabilities the carrier supports. Applications can prompt users to + * purchase these premium capabilities from their carrier for a network boost. + * Valid values are any of {@link TelephonyManager.PremiumCapability}. + * + * This is empty by default, indicating that no premium capabilities are supported. + * + * @see TelephonyManager#isPremiumCapabilityAvailableForPurchase(int) + * @see TelephonyManager#purchasePremiumCapability(int, Executor, Consumer) + */ + public static final String KEY_SUPPORTED_PREMIUM_CAPABILITIES_INT_ARRAY = + "supported_premium_capabilities_int_array"; + + /** + * The amount of time in milliseconds the notification for a network boost via + * premium capabilities will be visible to the user after + * {@link TelephonyManager#purchasePremiumCapability(int, Executor, Consumer)} + * requests user action to purchase the boost from the carrier. Once the timeout expires, + * the booster notification will be automatically dismissed and the request will fail with + * {@link TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_TIMEOUT}. + * + * The default value is 30 minutes. + */ + public static final String KEY_PREMIUM_CAPABILITY_NOTIFICATION_DISPLAY_TIMEOUT_MILLIS_LONG = + "premium_capability_notification_display_timeout_millis_long"; + + /** + * The amount of time in milliseconds that the notification for a network boost via + * premium capabilities should be blocked when + * {@link TelephonyManager#purchasePremiumCapability(int, Executor, Consumer)} + * returns a failure due to user action or timeout. + * + * The default value is 30 minutes. + * + * @see TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_CANCELED + * @see TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_TIMEOUT + */ + public static final String + KEY_PREMIUM_CAPABILITY_NOTIFICATION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG = + "premium_capability_notification_backoff_hysteresis_time_millis_long"; + + /** + * The amount of time in milliseconds that the purchase request should be throttled when + * {@link TelephonyManager#purchasePremiumCapability(int, Executor, Consumer)} + * returns a failure due to the carrier. + * + * The default value is 30 minutes. + * + * @see TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_CARRIER_ERROR + * @see TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_NETWORK_CONGESTED + */ + public static final String + KEY_PREMIUM_CAPABILITY_PURCHASE_CONDITION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG = + "premium_capability_purchase_condition_backoff_hysteresis_time_millis_long"; + + /** + * The URL to redirect to when the user clicks on the notification for a network boost via + * premium capabilities after applications call + * {@link TelephonyManager#purchasePremiumCapability(int, Executor, Consumer)}. + * If the URL is empty or invalid, the purchase request will return + * {@link TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_FEATURE_NOT_SUPPORTED}. + * + * This is empty by default. + */ + public static final String KEY_PREMIUM_CAPABILITY_PURCHASE_URL_STRING = + "premium_capability_purchase_url_string"; + + /** * IWLAN handover rules that determine whether handover is allowed or disallowed between * cellular and IWLAN. * @@ -9312,6 +9381,15 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_UNTHROTTLE_DATA_RETRY_WHEN_TAC_CHANGES_BOOL, false); sDefaults.putBoolean(KEY_VONR_SETTING_VISIBILITY_BOOL, true); sDefaults.putBoolean(KEY_VONR_ENABLED_BOOL, false); + sDefaults.putIntArray(KEY_SUPPORTED_PREMIUM_CAPABILITIES_INT_ARRAY, new int[]{}); + sDefaults.putLong(KEY_PREMIUM_CAPABILITY_NOTIFICATION_DISPLAY_TIMEOUT_MILLIS_LONG, + TimeUnit.MINUTES.toMillis(30)); + sDefaults.putLong(KEY_PREMIUM_CAPABILITY_NOTIFICATION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG, + TimeUnit.MINUTES.toMillis(30)); + sDefaults.putLong( + KEY_PREMIUM_CAPABILITY_PURCHASE_CONDITION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG, + TimeUnit.MINUTES.toMillis(30)); + sDefaults.putString(KEY_PREMIUM_CAPABILITY_PURCHASE_URL_STRING, null); sDefaults.putStringArray(KEY_IWLAN_HANDOVER_POLICY_STRING_ARRAY, new String[]{ "source=GERAN|UTRAN|EUTRAN|NGRAN|IWLAN, " + "target=GERAN|UTRAN|EUTRAN|NGRAN|IWLAN, type=allowed"}); diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index b4244dd09bbd..8818ac2f6ee0 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -17112,6 +17112,266 @@ public class TelephonyManager { } /** + * A premium capability boosting the network to allow real-time interactive traffic. + * Corresponds to NetworkCapabilities#NET_CAPABILITY_REALTIME_INTERACTIVE_TRAFFIC. + */ + // TODO(b/245748544): add @link once NET_CAPABILITY_REALTIME_INTERACTIVE_TRAFFIC is defined. + public static final int PREMIUM_CAPABILITY_REALTIME_INTERACTIVE_TRAFFIC = 1; + + /** + * Purchasable premium capabilities. + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = { "PREMIUM_CAPABILITY_" }, value = { + PREMIUM_CAPABILITY_REALTIME_INTERACTIVE_TRAFFIC}) + public @interface PremiumCapability {} + + /** + * Returns the premium capability {@link PremiumCapability} as a String. + * + * @param capability The premium capability. + * @return The premium capability as a String. + * @hide + */ + public static String convertPremiumCapabilityToString(@PremiumCapability int capability) { + switch (capability) { + case PREMIUM_CAPABILITY_REALTIME_INTERACTIVE_TRAFFIC: + return "REALTIME_INTERACTIVE_TRAFFIC"; + default: + return "UNKNOWN (" + capability + ")"; + } + } + + /** + * Check whether the given premium capability is available for purchase from the carrier. + * If this is {@code true}, the capability can be purchased from the carrier using + * {@link #purchasePremiumCapability(int, Executor, Consumer)}. + * + * @param capability The premium capability to check. + * @return Whether the given premium capability is available to purchase. + * @throws SecurityException if the caller does not hold permission READ_BASIC_PHONE_STATE. + */ + @RequiresPermission(android.Manifest.permission.READ_BASIC_PHONE_STATE) + public boolean isPremiumCapabilityAvailableForPurchase(@PremiumCapability int capability) { + try { + ITelephony telephony = getITelephony(); + if (telephony == null) { + throw new IllegalStateException("telephony service is null."); + } + return telephony.isPremiumCapabilityAvailableForPurchase(capability, getSubId()); + } catch (RemoteException ex) { + ex.rethrowAsRuntimeException(); + } + return false; + } + + /** + * Purchase premium capability request was successful. Subsequent attempts will return + * {@link #PURCHASE_PREMIUM_CAPABILITY_RESULT_ALREADY_PURCHASED} until the booster expires. + * The expiry time is determined by the type or duration of boost purchased from the carrier, + * provided at {@link CarrierConfigManager#KEY_PREMIUM_CAPABILITY_PURCHASE_URL_STRING}. + */ + public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_SUCCESS = 1; + + /** + * Purchase premium capability failed because the request is throttled for the amount of time + * specified by {@link CarrierConfigManager + * #KEY_PREMIUM_CAPABILITY_NOTIFICATION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG} + * or {@link CarrierConfigManager + * #KEY_PREMIUM_CAPABILITY_PURCHASE_CONDITION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG}. + * Subsequent attempts will return the same error until the request is no longer throttled + * or throttling conditions change. + */ + public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_THROTTLED = 2; + + /** + * Purchase premium capability failed because it is already purchased and available. + * Subsequent attempts will return the same error until the booster expires. + */ + public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_ALREADY_PURCHASED = 3; + + /** + * Purchase premium capability failed because a request was already made and is in progress. + * This may have been requested by either the same app or another app. + * Subsequent attempts will return the same error until the previous request completes. + */ + public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_ALREADY_IN_PROGRESS = 4; + + /** + * Purchase premium capability failed because the user disabled the feature. + * Subsequent attempts will return the same error until the user re-enables the feature. + */ + public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_DISABLED = 5; + + /** + * Purchase premium capability failed because the user canceled the operation. + * Subsequent attempts will be throttled for the amount of time specified by + * {@link CarrierConfigManager + * #KEY_PREMIUM_CAPABILITY_NOTIFICATION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG} + * and return {@link #PURCHASE_PREMIUM_CAPABILITY_RESULT_THROTTLED}. + */ + public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_CANCELED = 6; + + /** + * Purchase premium capability failed because the carrier disabled or does not support + * the capability, as specified in + * {@link CarrierConfigManager#KEY_SUPPORTED_PREMIUM_CAPABILITIES_INT_ARRAY}. + * Subsequent attempts will return the same error until the carrier enables the feature. + */ + public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_CARRIER_DISABLED = 7; + + /** + * Purchase premium capability failed because the carrier app did not indicate success. + * Subsequent attempts will be throttled for the amount of time specified by + * {@link CarrierConfigManager + * #KEY_PREMIUM_CAPABILITY_PURCHASE_CONDITION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG} + * and return {@link #PURCHASE_PREMIUM_CAPABILITY_RESULT_THROTTLED}. + */ + public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_CARRIER_ERROR = 8; + + /** + * Purchase premium capability failed because we did not receive a response from the user + * for the booster notification within the time specified by + * {@link CarrierConfigManager#KEY_PREMIUM_CAPABILITY_NOTIFICATION_DISPLAY_TIMEOUT_MILLIS_LONG}. + * The booster notification will be automatically dismissed and subsequent attempts will be + * throttled for the amount of time specified by + * {@link CarrierConfigManager + * #KEY_PREMIUM_CAPABILITY_NOTIFICATION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG} + * and return {@link #PURCHASE_PREMIUM_CAPABILITY_RESULT_THROTTLED}. + */ + public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_TIMEOUT = 9; + + /** + * Purchase premium capability failed because the device does not support the feature. + * Subsequent attempts will return the same error. + */ + public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_FEATURE_NOT_SUPPORTED = 10; + + /** + * Purchase premium capability failed because the telephony service is down or unavailable. + * Subsequent attempts will return the same error until request conditions are satisfied. + */ + public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_REQUEST_FAILED = 11; + + /** + * Purchase premium capability failed because the network is not available. + * Subsequent attempts will return the same error until network conditions change. + */ + public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_NETWORK_NOT_AVAILABLE = 12; + + /** + * Purchase premium capability failed because the network is congested. + * Subsequent attempts will be throttled for the amount of time specified by + * {@link CarrierConfigManager + * #KEY_PREMIUM_CAPABILITY_PURCHASE_CONDITION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG} + * and return {@link #PURCHASE_PREMIUM_CAPABILITY_RESULT_THROTTLED}. + * Throttling will be reevaluated when the network is no longer congested. + */ + public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_NETWORK_CONGESTED = 13; + + /** + * Results of the purchase premium capability request. + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = { "PURCHASE_PREMIUM_CAPABILITY_RESULT_" }, value = { + PURCHASE_PREMIUM_CAPABILITY_RESULT_SUCCESS, + PURCHASE_PREMIUM_CAPABILITY_RESULT_THROTTLED, + PURCHASE_PREMIUM_CAPABILITY_RESULT_ALREADY_PURCHASED, + PURCHASE_PREMIUM_CAPABILITY_RESULT_ALREADY_IN_PROGRESS, + PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_DISABLED, + PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_CANCELED, + PURCHASE_PREMIUM_CAPABILITY_RESULT_CARRIER_DISABLED, + PURCHASE_PREMIUM_CAPABILITY_RESULT_CARRIER_ERROR, + PURCHASE_PREMIUM_CAPABILITY_RESULT_TIMEOUT, + PURCHASE_PREMIUM_CAPABILITY_RESULT_FEATURE_NOT_SUPPORTED, + PURCHASE_PREMIUM_CAPABILITY_RESULT_NETWORK_NOT_AVAILABLE, + PURCHASE_PREMIUM_CAPABILITY_RESULT_NETWORK_CONGESTED}) + public @interface PurchasePremiumCapabilityResult {} + + /** + * Returns the purchase result {@link PurchasePremiumCapabilityResult} as a String. + * + * @param result The purchase premium capability result. + * @return The purchase result as a String. + * @hide + */ + public static String convertPurchaseResultToString( + @PurchasePremiumCapabilityResult int result) { + switch (result) { + case PURCHASE_PREMIUM_CAPABILITY_RESULT_SUCCESS: + return "SUCCESS"; + case PURCHASE_PREMIUM_CAPABILITY_RESULT_THROTTLED: + return "THROTTLED"; + case PURCHASE_PREMIUM_CAPABILITY_RESULT_ALREADY_PURCHASED: + return "ALREADY_PURCHASED"; + case PURCHASE_PREMIUM_CAPABILITY_RESULT_ALREADY_IN_PROGRESS: + return "ALREADY_IN_PROGRESS"; + case PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_DISABLED: + return "USER_DISABLED"; + case PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_CANCELED: + return "USER_CANCELED"; + case PURCHASE_PREMIUM_CAPABILITY_RESULT_CARRIER_DISABLED: + return "CARRIER_DISABLED"; + case PURCHASE_PREMIUM_CAPABILITY_RESULT_CARRIER_ERROR: + return "CARRIER_ERROR"; + case PURCHASE_PREMIUM_CAPABILITY_RESULT_TIMEOUT: + return "TIMEOUT"; + case PURCHASE_PREMIUM_CAPABILITY_RESULT_FEATURE_NOT_SUPPORTED: + return "FEATURE_NOT_SUPPORTED"; + case PURCHASE_PREMIUM_CAPABILITY_RESULT_REQUEST_FAILED: + return "REQUEST_FAILED"; + case PURCHASE_PREMIUM_CAPABILITY_RESULT_NETWORK_NOT_AVAILABLE: + return "NETWORK_NOT_AVAILABLE"; + case PURCHASE_PREMIUM_CAPABILITY_RESULT_NETWORK_CONGESTED: + return "NETWORK_CONGESTED"; + default: + return "UNKNOWN (" + result + ")"; + } + } + + /** + * Purchase the given premium capability from the carrier. + * This requires user action to purchase the boost from the carrier. + * If this returns {@link #PURCHASE_PREMIUM_CAPABILITY_RESULT_SUCCESS} or + * {@link #PURCHASE_PREMIUM_CAPABILITY_RESULT_ALREADY_PURCHASED}, applications can request + * the premium capability via {@link ConnectivityManager#requestNetwork}. + * + * @param capability The premium capability to purchase. + * @param executor The callback executor for the response. + * @param callback The result of the purchase request. + * One of {@link PurchasePremiumCapabilityResult}. + * @throws SecurityException if the caller does not hold permission READ_BASIC_PHONE_STATE. + * @see #isPremiumCapabilityAvailableForPurchase(int) to check whether the capability is valid + */ + @RequiresPermission(android.Manifest.permission.READ_BASIC_PHONE_STATE) + public void purchasePremiumCapability(@PremiumCapability int capability, + @NonNull @CallbackExecutor Executor executor, + @NonNull @PurchasePremiumCapabilityResult Consumer<Integer> callback) { + Objects.requireNonNull(executor); + Objects.requireNonNull(callback); + + IIntegerConsumer internalCallback = new IIntegerConsumer.Stub() { + @Override + public void accept(int result) { + executor.execute(() -> callback.accept(result)); + } + }; + + try { + ITelephony telephony = getITelephony(); + if (telephony == null) { + callback.accept(PURCHASE_PREMIUM_CAPABILITY_RESULT_REQUEST_FAILED); + return; + } + telephony.purchasePremiumCapability(capability, internalCallback, getSubId()); + } catch (RemoteException ex) { + callback.accept(PURCHASE_PREMIUM_CAPABILITY_RESULT_REQUEST_FAILED); + } + } + + /** * Get last known cell identity. * Require {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and * com.android.phone.permission.ACCESS_LAST_KNOWN_CELL_ID, otherwise throws SecurityException. diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 850d26801f17..648866b6662d 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -2529,6 +2529,16 @@ interface ITelephony { void getSlicingConfig(in ResultReceiver callback); /** + * Check whether the given premium capability is available for purchase from the carrier. + */ + boolean isPremiumCapabilityAvailableForPurchase(int capability, int subId); + + /** + * Purchase the given premium capability from the carrier. + */ + void purchasePremiumCapability(int capability, IIntegerConsumer callback, int subId); + + /** * Register an IMS connection state callback */ void registerImsStateCallback(int subId, int feature, in IImsStateCallback cb, |