Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e92ddfef authored by Hui Wang's avatar Hui Wang
Browse files

RCS Provisioning APIs for Single Registration

Bug: 154864150
Test: atest FrameworksTelephonyTests:com.telephony.ims.RcsConfigTest
Test: atest TeleServiceTests:com.android.phone.RcsProvisioningMonitorTest
Test: atest CtsTelephonyTestCases:android.telephony.ims.cts.ImsServiceTest
Merged-In: Ie9445dd450d175e0dc94b63b487dda5cde729123
Change-Id: Ie9445dd450d175e0dc94b63b487dda5cde729123
parent 777f0ea9
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -40253,6 +40253,7 @@ package android.telephony {
    field public static final String KEY_TREAT_DOWNGRADED_VIDEO_CALLS_AS_VIDEO_CALLS_BOOL = "treat_downgraded_video_calls_as_video_calls_bool";
    field public static final String KEY_TTY_SUPPORTED_BOOL = "tty_supported_bool";
    field public static final String KEY_UNLOGGABLE_NUMBERS_STRING_ARRAY = "unloggable_numbers_string_array";
    field public static final String KEY_USE_ACS_FOR_RCS_BOOL = "use_acs_for_rcs_bool";
    field public static final String KEY_USE_HFA_FOR_PROVISIONING_BOOL = "use_hfa_for_provisioning_bool";
    field public static final String KEY_USE_OTASP_FOR_PROVISIONING_BOOL = "use_otasp_for_provisioning_bool";
    field public static final String KEY_USE_RCS_PRESENCE_BOOL = "use_rcs_presence_bool";
+36 −0
Original line number Diff line number Diff line
@@ -11441,18 +11441,29 @@ package android.telephony.ims {
    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public boolean getProvisioningStatusForCapability(int, int);
    method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public String getProvisioningStringValue(int);
    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public boolean getRcsProvisioningStatusForCapability(int);
    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isRcsVolteSingleRegistrationCapable() throws android.telephony.ims.ImsException;
    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyRcsAutoConfigurationReceived(@NonNull byte[], boolean);
    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerProvisioningChangedCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ProvisioningManager.Callback) throws android.telephony.ims.ImsException;
    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerRcsProvisioningChangedCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ProvisioningManager.RcsProvisioningCallback) throws android.telephony.ims.ImsException;
    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningIntValue(int, int);
    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void setProvisioningStatusForCapability(int, int, boolean);
    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningStringValue(int, @NonNull String);
    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setRcsClientConfiguration(@NonNull android.telephony.ims.RcsClientConfiguration) throws android.telephony.ims.ImsException;
    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void setRcsProvisioningStatusForCapability(int, boolean);
    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void triggerRcsReconfiguration();
    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterProvisioningChangedCallback(@NonNull android.telephony.ims.ProvisioningManager.Callback);
    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterRcsProvisioningChangedCallback(@NonNull android.telephony.ims.ProvisioningManager.RcsProvisioningCallback);
    field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final String ACTION_RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE = "android.telephony.ims.action.RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE";
    field public static final String EXTRA_STATUS = "android.telephony.ims.extra.STATUS";
    field public static final String EXTRA_SUBSCRIPTION_ID = "android.telephony.ims.extra.SUBSCRIPTION_ID";
    field public static final int KEY_VOICE_OVER_WIFI_ENTITLEMENT_ID = 67; // 0x43
    field public static final int KEY_VOICE_OVER_WIFI_MODE_OVERRIDE = 27; // 0x1b
    field public static final int KEY_VOICE_OVER_WIFI_ROAMING_ENABLED_OVERRIDE = 26; // 0x1a
    field public static final int PROVISIONING_VALUE_DISABLED = 0; // 0x0
    field public static final int PROVISIONING_VALUE_ENABLED = 1; // 0x1
    field public static final int STATUS_CAPABLE = 0; // 0x0
    field public static final int STATUS_CARRIER_NOT_CAPABLE = 2; // 0x2
    field public static final int STATUS_DEVICE_NOT_CAPABLE = 1; // 0x1
    field public static final String STRING_QUERY_RESULT_ERROR_GENERIC = "STRING_QUERY_RESULT_ERROR_GENERIC";
    field public static final String STRING_QUERY_RESULT_ERROR_NOT_READY = "STRING_QUERY_RESULT_ERROR_NOT_READY";
  }
@@ -11463,6 +11474,27 @@ package android.telephony.ims {
    method public void onProvisioningStringChanged(int, @NonNull String);
  }
  public static class ProvisioningManager.RcsProvisioningCallback {
    ctor public ProvisioningManager.RcsProvisioningCallback();
    method public void onAutoConfigurationErrorReceived(int, @NonNull String);
    method public void onConfigurationChanged(@NonNull byte[]);
    method public void onConfigurationReset();
    method public void onRemoved();
  }
  public final class RcsClientConfiguration implements android.os.Parcelable {
    ctor public RcsClientConfiguration(@NonNull String, @NonNull String, @NonNull String, @NonNull String);
    method public int describeContents();
    method @NonNull public String getClientVendor();
    method @NonNull public String getClientVersion();
    method @NonNull public String getRcsProfile();
    method @NonNull public String getRcsVersion();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.RcsClientConfiguration> CREATOR;
    field public static final String RCS_PROFILE_1_0 = "UP_1.0";
    field public static final String RCS_PROFILE_2_3 = "UP_2.3";
  }
  public class RcsUceAdapter {
    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUceSettingEnabled(boolean) throws android.telephony.ims.ImsException;
  }
@@ -11750,11 +11782,15 @@ package android.telephony.ims.stub {
    ctor public ImsConfigImplBase();
    method public int getConfigInt(int);
    method public String getConfigString(int);
    method public final void notifyAutoConfigurationErrorReceived(int, @NonNull String);
    method public final void notifyProvisionedValueChanged(int, int);
    method public final void notifyProvisionedValueChanged(int, String);
    method public void notifyRcsAutoConfigurationReceived(@NonNull byte[], boolean);
    method public void notifyRcsAutoConfigurationRemoved();
    method public int setConfig(int, int);
    method public int setConfig(int, String);
    method public void setRcsClientConfiguration(@NonNull android.telephony.ims.RcsClientConfiguration);
    method public void triggerAutoConfiguration();
    field public static final int CONFIG_RESULT_FAILED = 1; // 0x1
    field public static final int CONFIG_RESULT_SUCCESS = 0; // 0x0
    field public static final int CONFIG_RESULT_UNKNOWN = -1; // 0xffffffff
+8 −0
Original line number Diff line number Diff line
@@ -5270,5 +5270,13 @@ public final class Telephony {
         * @hide
         */
        public static final String COLUMN_ALLOWED_NETWORK_TYPES = "allowed_network_types";

        /**
         * TelephonyProvider column name for RCS configuration.
         * <p>TYPE: BLOB
         *
         * @hide
         */
        public static final String COLUMN_RCS_CONFIG = "rcs_config";
    }
}
+7 −0
Original line number Diff line number Diff line
@@ -4018,6 +4018,12 @@ public class CarrierConfigManager {
    public static final String KEY_USE_LOWER_MTU_VALUE_IF_BOTH_RECEIVED =
            "use_lower_mtu_value_if_both_received";

    /**
     * Indicates if auto-configuration server is used for the RCS config
     * Reference: GSMA RCC.14
     */
    public static final String KEY_USE_ACS_FOR_RCS_BOOL = "use_acs_for_rcs_bool";

    /** The default value for every variable. */
    private final static PersistableBundle sDefaults;

@@ -4561,6 +4567,7 @@ public class CarrierConfigManager {
        sDefaults.putBoolean(KEY_DISABLE_DUN_APN_WHILE_ROAMING_WITH_PRESET_APN_BOOL, false);
        sDefaults.putString(KEY_DEFAULT_PREFERRED_APN_NAME_STRING, "");
        sDefaults.putBoolean(KEY_USE_LOWER_MTU_VALUE_IF_BOTH_RECEIVED, false);
        sDefaults.putBoolean(KEY_USE_ACS_FOR_RCS_BOOL, false);
    }

    /**
+279 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.StringDef;
import android.annotation.SystemApi;
import android.annotation.WorkerThread;
@@ -31,6 +32,7 @@ import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyFrameworkInitializer;
import android.telephony.ims.aidl.IImsConfigCallback;
import android.telephony.ims.aidl.IRcsConfigCallback;
import android.telephony.ims.feature.MmTelFeature;
import android.telephony.ims.feature.RcsFeature;
import android.telephony.ims.stub.ImsConfigImplBase;
@@ -935,6 +937,115 @@ public class ProvisioningManager {

    private int mSubId;

    /**
     * The callback for RCS provisioning changes.
     */
    public static class RcsProvisioningCallback {
        private static class CallbackBinder extends IRcsConfigCallback.Stub {

            private final RcsProvisioningCallback mLocalCallback;
            private Executor mExecutor;

            private CallbackBinder(RcsProvisioningCallback localCallback) {
                mLocalCallback = localCallback;
            }

            @Override
            public void onConfigurationChanged(byte[] configXml) {
                final long identity = Binder.clearCallingIdentity();
                try {
                    mExecutor.execute(() -> mLocalCallback.onConfigurationChanged(configXml));
                } finally {
                    Binder.restoreCallingIdentity(identity);
                }
            }

            @Override
            public void onAutoConfigurationErrorReceived(int errorCode, String errorString) {
                final long identity = Binder.clearCallingIdentity();
                try {
                    mExecutor.execute(() -> mLocalCallback.onAutoConfigurationErrorReceived(
                            errorCode, errorString));
                } finally {
                    Binder.restoreCallingIdentity(identity);
                }
            }

            @Override
            public void onConfigurationReset() {
                final long identity = Binder.clearCallingIdentity();
                try {
                    mExecutor.execute(() -> mLocalCallback.onConfigurationReset());
                } finally {
                    Binder.restoreCallingIdentity(identity);
                }
            }

            @Override
            public void onRemoved() {
                final long identity = Binder.clearCallingIdentity();
                try {
                    mExecutor.execute(() -> mLocalCallback.onRemoved());
                } finally {
                    Binder.restoreCallingIdentity(identity);
                }
            }

            private void setExecutor(Executor executor) {
                mExecutor = executor;
            }
        }

        private final CallbackBinder mBinder = new CallbackBinder(this);

        /**
         * RCS configuration received via OTA provisioning. Configuration may change
         * due to various triggers defined in GSMA RCC.14 for ACS(auto configuration
         * server) or other operator defined triggers. If RCS provisioning is already
         * completed at the time of callback registration, then this method shall be
         * invoked with the current configuration
         * @param configXml The RCS configurationXML received OTA.
         */
        public void onConfigurationChanged(@NonNull byte[] configXml) {}

        /**
         * Errors during autoconfiguration connection setup are notified by the
         * ACS(auto configuration server) client using this interface.
         * @param errorCode HTTP error received during connection setup defined in
         * GSMA RCC.14 2.4.3, like {@link java.net.HttpURLConnection#HTTP_UNAUTHORIZED},
         * {@link java.net.HttpURLConnection#HTTP_FORBIDDEN}, etc.
         * @param errorString reason phrase received with the error
         */
        public void onAutoConfigurationErrorReceived(int errorCode,
                @NonNull String errorString) {}

        /**
         * When the previously valid RCS configuration is cleaned up by telephony for
         * any case like SIM removed, default messaging application changed, etc.,
         * this method will be invoked to notify the application regarding this change.
         */
        public void onConfigurationReset() {}

        /**
         * When the RCS application is no longer the Default messaging application,
         * or when the subscription associated with this callback is removed (SIM
         * removed, ESIM swap,etc...), callback will automatically be removed and
         * the below method is invoked. There is a possibility that the method is
         * invoked after the subscription has become inactive
         */
        public void onRemoved() {}

        /**@hide*/
        public final IRcsConfigCallback getBinder() {
            return mBinder;
        }

        /**@hide*/
        public void setExecutor(Executor executor) {
            mBinder.setExecutor(executor);
        }
    }

    /**
     * Create a new {@link ProvisioningManager} for the subscription specified.
     *
@@ -1207,6 +1318,174 @@ public class ProvisioningManager {

    }

    /**
     * Provides the single registration capability of the device and the carrier.
     *
     * <p>This intent only provides the capability and not the current provisioning status of
     * the RCS VoLTE single registration feature. Only default messaging application may receive
     * the intent.
     *
     * <p>Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to specify the subscription index for which
     * the intent is valid. and {@link #EXTRA_STATUS} to specify RCS VoLTE single registration
     * status.
     */
    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
    @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE =
            "android.telephony.ims.action.RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE";

    /**
     * Integer extra to specify subscription index.
     */
    public static final String EXTRA_SUBSCRIPTION_ID =
            "android.telephony.ims.extra.SUBSCRIPTION_ID";

    /**
     * Integer extra to specify RCS single registration status
     *
     * <p>The value can be {@link #STATUS_CAPABLE}, {@link #STATUS_DEVICE_NOT_CAPABLE},
     * {@link #STATUS_CARRIER_NOT_CAPABLE}, or bitwise OR of
     * {@link #STATUS_DEVICE_NOT_CAPABLE} and {@link #STATUS_CARRIER_NOT_CAPABLE}.
     */
    public static final String EXTRA_STATUS = "android.telephony.ims.extra.STATUS";

    /**
     * RCS VoLTE single registration is supported by the device and carrier.
     */
    public static final int STATUS_CAPABLE                       = 0;

    /**
     * RCS VoLTE single registration is not supported by the device.
     */
    public static final int STATUS_DEVICE_NOT_CAPABLE            = 0x01;

    /**
     * RCS VoLTE single registration is not supported by the carrier
     */
    public static final int STATUS_CARRIER_NOT_CAPABLE           = 0x01 << 1;

    /**
     * Provide the client configuration parameters of the RCS application.
     *
     * <p>When this application is also the default messaging application, and RCS
     * provisioning is done using autoconfiguration, then these parameters shall be
     * sent in the HTTP get request to fetch the RCS provisioning. RCS client
     * configuration must be provided by the application before registering for the
     * provisioning status events {@link #registerRcsProvisioningChangedCallback()}
     * @param rcc RCS client configuration {@link RcsClientConfiguration}
     */
    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
    public void setRcsClientConfiguration(
            @NonNull RcsClientConfiguration rcc) throws ImsException {
        try {
            getITelephony().setRcsClientConfiguration(mSubId, rcc);
        } catch (ServiceSpecificException e) {
            throw new ImsException(e.getMessage(), e.errorCode);
        } catch (RemoteException | IllegalStateException e) {
            throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
        }
    }

    /**
     * Returns a flag to indicate if the device software and the carrier
     * have the capability to support RCS Volte single IMS registration.
     * @return true if this single registration is capable, false otherwise
     * @throws ImsException If the remote ImsService is not available for
     * any reason or the subscription associated with this instance is no
     * longer active. See {@link ImsException#getCode()} for more
     * information.
     */
    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
    public boolean isRcsVolteSingleRegistrationCapable() throws ImsException {
        try {
            return getITelephony().isRcsVolteSingleRegistrationCapable(mSubId);
        } catch (RemoteException | IllegalStateException e) {
            throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
        }
    }

   /**
     * Registers a new {@link RcsProvisioningCallback} to listen to changes to
     * RCS provisioning xml.
     *
     * <p>RCS application must be the default messaging application and must
     * have already registered its {@link RcsClientConfiguration} by using
     * {@link #setRcsClientConfiguration} before it registers the provisioning
     * callback. If ProvisioningManager has a valid RCS configuration at the
     * time of callback registration and a reconfiguration is not required
     * due to RCS client parameters change, then the callback shall be invoked
     * immediately with the xml.
     * When the subscription associated with this callback is removed (SIM removed,
     * ESIM swap,etc...), this callback will automatically be removed.
     *
     * @param executor The {@link Executor} to call the callback methods on
     * @param callback The rcs provisioning callback to be registered.
     * @see #unregisterRcsProvisioningChangedCallback(RcsProvisioningCallback)
     * @see SubscriptionManager.OnSubscriptionsChangedListener
     * @throws IllegalArgumentException if the subscription associated with this
     * callback is not active (SIM is not inserted, ESIM inactive) or the
     * subscription is invalid.
     * @throws ImsException if the subscription associated with this callback is
     * valid, but the {@link ImsService} associated with the subscription is not
     * available. This can happen if the service crashed, for example.
     * It shall also throw this exception when the RCS client parameters for the
     * application are not valid. In that case application must set the client
     * params (See {@link #setRcsClientConfiguration()}) and re register the
     * callback.
     * See {@link ImsException#getCode()} for a more detailed reason.
     */
    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
    public void registerRcsProvisioningChangedCallback(
            @NonNull @CallbackExecutor Executor executor,
            @NonNull RcsProvisioningCallback callback) throws ImsException {
        callback.setExecutor(executor);
        try {
            getITelephony().registerRcsProvisioningChangedCallback(mSubId, callback.getBinder());
        } catch (ServiceSpecificException e) {
            throw new ImsException(e.getMessage(), e.errorCode);
        } catch (RemoteException | IllegalStateException e) {
            throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
        }
    }

    /**
     * Unregister an existing {@link RcsProvisioningCallback}. Application can
     * unregister when its no longer interested in the provisioning updates
     * like when a user disables RCS from the UI/settings.
     * When the subscription associated with this callback is removed (SIM
     * removed, ESIM swap, etc...), this callback will automatically be
     * removed. If this method is called for an inactive subscription, it
     * will result in a no-op.
     * @param callback The existing {@link RcsProvisioningCallback} to be
     * removed.
     * @see #registerRcsProvisioningChangedCallback(RcsClientConfiguration,
     * Executor, RcsProvisioningCallback) @throws IllegalArgumentException
     * if the subscription associated with this callback is invalid.
     */
    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
    public void unregisterRcsProvisioningChangedCallback(
            @NonNull RcsProvisioningCallback callback) {
        try {
            getITelephony().unregisterRcsProvisioningChangedCallback(
                    mSubId, callback.getBinder());
        } catch (RemoteException e) {
            throw e.rethrowAsRuntimeException();
        }
    }

    /**
     * Reconfiguration triggered by the RCS application. Most likely cause
     * is the 403 forbidden to a HTTP request.
     */
    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
    public void triggerRcsReconfiguration() {
        try {
            getITelephony().triggerRcsReconfiguration(mSubId);
        } catch (RemoteException e) {
            throw e.rethrowAsRuntimeException();
        }
    }

    private static ITelephony getITelephony() {
        ITelephony binder = ITelephony.Stub.asInterface(
                TelephonyFrameworkInitializer
Loading