summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHui Wang <huiwang@google.com>2020-12-17 22:53:31 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2020-12-17 22:53:31 +0000
commit7c9eef5613cd6e9716dd608cbc08715c4f2ff19f (patch)
tree5aa813df5687e192255637c07ab21ac368de3987
parentb8ff8f238e20cefbe4654d64b69cb7d003ce4610 (diff)
parente92ddfef4ff3aee092f09682704fc716fef44432 (diff)
Merge "RCS Provisioning APIs for Single Registration"
-rw-r--r--core/api/current.txt1
-rw-r--r--core/api/system-current.txt36
-rw-r--r--core/java/android/provider/Telephony.java8
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java7
-rw-r--r--telephony/java/android/telephony/ims/ProvisioningManager.java279
-rw-r--r--telephony/java/android/telephony/ims/RcsClientConfiguration.aidl19
-rw-r--r--telephony/java/android/telephony/ims/RcsClientConfiguration.java162
-rw-r--r--telephony/java/android/telephony/ims/RcsConfig.aidl19
-rw-r--r--telephony/java/android/telephony/ims/RcsConfig.java306
-rw-r--r--telephony/java/android/telephony/ims/aidl/IImsConfig.aidl8
-rw-r--r--telephony/java/android/telephony/ims/aidl/IRcsConfigCallback.aidl29
-rw-r--r--telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java123
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl49
13 files changed, 1044 insertions, 2 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index 6e8adff46b16..3644eb8c3fd4 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -40254,6 +40254,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";
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 572d6e6c2cfc..cbd65d174fb0 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -11448,18 +11448,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";
}
@@ -11470,6 +11481,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;
}
@@ -11758,11 +11790,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
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index 99c82c507ae8..727769cb5ab8 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -5278,5 +5278,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";
}
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 27ea6902146f..11bb8674d5a9 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -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);
}
/**
diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java
index 0fe76a04bf9d..f3c38bcba98a 100644
--- a/telephony/java/android/telephony/ims/ProvisioningManager.java
+++ b/telephony/java/android/telephony/ims/ProvisioningManager.java
@@ -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;
@@ -936,6 +938,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.
*
* @param subId The ID of the subscription that this ProvisioningManager will use.
@@ -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
diff --git a/telephony/java/android/telephony/ims/RcsClientConfiguration.aidl b/telephony/java/android/telephony/ims/RcsClientConfiguration.aidl
new file mode 100644
index 000000000000..a702f0f42c54
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsClientConfiguration.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+parcelable RcsClientConfiguration;
diff --git a/telephony/java/android/telephony/ims/RcsClientConfiguration.java b/telephony/java/android/telephony/ims/RcsClientConfiguration.java
new file mode 100644
index 000000000000..793c37745de6
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsClientConfiguration.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import android.annotation.NonNull;
+import android.annotation.StringDef;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * The container of RCS application related configs.
+ *
+ * @hide
+ */
+@SystemApi
+public final class RcsClientConfiguration implements Parcelable {
+
+ /**@hide*/
+ @StringDef(prefix = "RCS_PROFILE_",
+ value = {RCS_PROFILE_1_0, RCS_PROFILE_2_3})
+ public @interface StringRcsProfile {}
+
+ /**
+ * RCS profile UP 1.0
+ */
+ public static final String RCS_PROFILE_1_0 = "UP_1.0";
+ /**
+ * RCS profile UP 2.3
+ */
+ public static final String RCS_PROFILE_2_3 = "UP_2.3";
+
+ private String mRcsVersion;
+ private String mRcsProfile;
+ private String mClientVendor;
+ private String mClientVersion;
+
+ /**
+ * Create a RcsClientConfiguration object.
+ * Default messaging application must pass a valid configuration object
+ * @param rcsVersion The parameter identifies the RCS version supported
+ * by the client. Refer to GSMA RCC.07 "rcs_version" parameter.
+ * @param rcsProfile Identifies a fixed set of RCS services that are
+ * supported by the client. See {@link #RCS_PROFILE_1_0 } or
+ * {@link #RCS_PROFILE_2_3 }
+ * @param clientVendor Identifies the vendor providing the RCS client.
+ * @param clientVersion Identifies the RCS client version. Refer to GSMA
+ * RCC.07 "client_version" parameter.
+ * Example:client_version=RCSAndrd-1.0
+ */
+ public RcsClientConfiguration(@NonNull String rcsVersion,
+ @NonNull @StringRcsProfile String rcsProfile,
+ @NonNull String clientVendor, @NonNull String clientVersion) {
+ mRcsVersion = rcsVersion;
+ mRcsProfile = rcsProfile;
+ mClientVendor = clientVendor;
+ mClientVersion = clientVersion;
+ }
+
+ /**
+ * Returns RCS version supported.
+ */
+ public @NonNull String getRcsVersion() {
+ return mRcsVersion;
+ }
+
+ /**
+ * Returns RCS profile supported.
+ */
+ public @NonNull @StringRcsProfile String getRcsProfile() {
+ return mRcsProfile;
+ }
+
+ /**
+ * Returns the name of the vendor providing the RCS client.
+ */
+ public @NonNull String getClientVendor() {
+ return mClientVendor;
+ }
+
+ /**
+ * Returns the RCS client version.
+ */
+ public @NonNull String getClientVersion() {
+ return mClientVersion;
+ }
+
+ /**
+ * {@link Parcelable#writeToParcel}
+ */
+ @Override
+ public void writeToParcel(@NonNull Parcel out, int flags) {
+ out.writeString(mRcsVersion);
+ out.writeString(mRcsProfile);
+ out.writeString(mClientVendor);
+ out.writeString(mClientVersion);
+ }
+
+ /**
+ * {@link Parcelable.Creator}
+ *
+ */
+ public static final @android.annotation.NonNull Parcelable.Creator<
+ RcsClientConfiguration> CREATOR = new Creator<RcsClientConfiguration>() {
+ @Override
+ public RcsClientConfiguration createFromParcel(Parcel in) {
+ String rcsVersion = in.readString();
+ String rcsProfile = in.readString();
+ String clientVendor = in.readString();
+ String clientVersion = in.readString();
+ return new RcsClientConfiguration(rcsVersion, rcsProfile,
+ clientVendor, clientVersion);
+ }
+
+ @Override
+ public RcsClientConfiguration[] newArray(int size) {
+ return new RcsClientConfiguration[size];
+ }
+ };
+
+ /**
+ * {@link Parcelable#describeContents}
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof RcsClientConfiguration)) {
+ return false;
+ }
+
+ RcsClientConfiguration other = (RcsClientConfiguration) obj;
+
+ return mRcsVersion.equals(other.mRcsVersion) && mRcsProfile.equals(other.mRcsProfile)
+ && mClientVendor.equals(other.mClientVendor)
+ && mClientVersion.equals(other.mClientVersion);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mRcsVersion, mRcsProfile, mClientVendor, mClientVersion);
+ }
+}
diff --git a/telephony/java/android/telephony/ims/RcsConfig.aidl b/telephony/java/android/telephony/ims/RcsConfig.aidl
new file mode 100644
index 000000000000..cfd93fbe2edb
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsConfig.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+parcelable RcsConfig;
diff --git a/telephony/java/android/telephony/ims/RcsConfig.java b/telephony/java/android/telephony/ims/RcsConfig.java
new file mode 100644
index 000000000000..07e95cc99290
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsConfig.java
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.os.Build;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.provider.Telephony.SimInfo;
+import android.text.TextUtils;
+
+import com.android.telephony.Rlog;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+/**
+ * RCS config data and methods to process the config
+ * @hide
+ */
+public final class RcsConfig implements Parcelable {
+ private static final String LOG_TAG = "RcsConfig";
+ private static final boolean DBG = Build.IS_ENG;
+
+ private final HashMap<String, String> mValues = new HashMap<>();
+
+ private RcsConfig(HashMap<String, String> values) {
+ mValues.putAll(values);
+ }
+
+ public RcsConfig(byte[] data) throws IllegalArgumentException {
+ if (data == null || data.length == 0) {
+ throw new IllegalArgumentException("Empty data");
+ }
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
+ try {
+ XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
+ factory.setNamespaceAware(true);
+ XmlPullParser xpp = factory.newPullParser();
+ xpp.setInput(inputStream, null);
+ int eventType = xpp.getEventType();
+ String tag = null;
+ while (eventType != XmlPullParser.END_DOCUMENT) {
+ if (eventType == XmlPullParser.START_TAG) {
+ tag = xpp.getName().trim();
+ } else if (eventType == XmlPullParser.END_TAG) {
+ tag = null;
+ } else if (eventType == XmlPullParser.TEXT) {
+ String value = xpp.getText().trim();
+ if (!TextUtils.isEmpty(tag) && !TextUtils.isEmpty(value)) {
+ mValues.put(tag, value);
+ }
+ }
+ eventType = xpp.next();
+ }
+ } catch (IOException | XmlPullParserException e) {
+ throw new IllegalArgumentException(e);
+ } finally {
+ try {
+ inputStream.close();
+ } catch (IOException e) {
+ loge("error to close input stream, skip.");
+ }
+ }
+ }
+
+ /**
+ * Retrieve a String value of the config item with the tag
+ *
+ * @param tag The name of the config to retrieve.
+ * @param defaultVal Value to return if the config does not exist.
+ *
+ * @return Returns the config value if it exists, or defaultVal.
+ */
+ public @Nullable String getString(@NonNull String tag, @Nullable String defaultVal) {
+ return mValues.containsKey(tag) ? mValues.get(tag) : defaultVal;
+ }
+
+ /**
+ * Retrieve a int value of the config item with the tag
+ *
+ * @param tag The name of the config to retrieve.
+ * @param defaultVal Value to return if the config does not exist or not valid.
+ *
+ * @return Returns the config value if it exists and is a valid int, or defaultVal.
+ */
+ public int getInteger(@NonNull String tag, int defaultVal) {
+ try {
+ return Integer.parseInt(mValues.get(tag));
+ } catch (NumberFormatException e) {
+ logd("error to getInteger for " + tag + " due to " + e);
+ }
+ return defaultVal;
+ }
+
+ /**
+ * Retrieve a boolean value of the config item with the tag
+ *
+ * @param tag The name of the config to retrieve.
+ * @param defaultVal Value to return if the config does not exist.
+ *
+ * @return Returns the config value if it exists, or defaultVal.
+ */
+ public boolean getBoolean(@NonNull String tag, boolean defaultVal) {
+ if (!mValues.containsKey(tag)) {
+ return defaultVal;
+ }
+ return Boolean.parseBoolean(mValues.get(tag));
+ }
+
+ /**
+ * Check whether the config item exists
+ *
+ * @param tag The name of the config to retrieve.
+ *
+ * @return Returns true if it exists, or false.
+ */
+ public boolean hasConfig(@NonNull String tag) {
+ return mValues.containsKey(tag);
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("[RCS Config]");
+ if (DBG) {
+ mValues.forEach((t, v) -> {
+ sb.append("\n");
+ sb.append(t);
+ sb.append(" : ");
+ sb.append(v);
+ });
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof RcsConfig)) {
+ return false;
+ }
+
+ RcsConfig other = (RcsConfig) obj;
+
+ return mValues.equals(other.mValues);
+ }
+
+ @Override
+ public int hashCode() {
+ return mValues.hashCode();
+ }
+
+ /**
+ * compress the gzip format data
+ */
+ public static @Nullable byte[] compressGzip(@NonNull byte[] data) {
+ if (data == null || data.length == 0) {
+ return data;
+ }
+ byte[] out = null;
+ try {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
+ GZIPOutputStream gzipCompressingStream =
+ new GZIPOutputStream(outputStream);
+ gzipCompressingStream.write(data);
+ gzipCompressingStream.close();
+ out = outputStream.toByteArray();
+ outputStream.close();
+ } catch (IOException e) {
+ loge("Error to compressGzip due to " + e);
+ }
+ return out;
+ }
+
+ /**
+ * decompress the gzip format data
+ */
+ public static @Nullable byte[] decompressGzip(@NonNull byte[] data) {
+ if (data == null || data.length == 0) {
+ return data;
+ }
+ byte[] out = null;
+ try {
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ GZIPInputStream gzipDecompressingStream =
+ new GZIPInputStream(inputStream);
+ byte[] buf = new byte[1024];
+ int size = gzipDecompressingStream.read(buf);
+ while (size >= 0) {
+ outputStream.write(buf, 0, size);
+ size = gzipDecompressingStream.read(buf);
+ }
+ gzipDecompressingStream.close();
+ inputStream.close();
+ out = outputStream.toByteArray();
+ outputStream.close();
+ } catch (IOException e) {
+ loge("Error to decompressGzip due to " + e);
+ }
+ return out;
+ }
+
+ /**
+ * save the config to siminfo db. It is only used internally.
+ */
+ public static void updateConfigForSub(@NonNull Context cxt, int subId,
+ @NonNull byte[] config, boolean isCompressed) {
+ //always store gzip compressed data
+ byte[] data = isCompressed ? config : compressGzip(config);
+ ContentValues values = new ContentValues();
+ values.put(SimInfo.COLUMN_RCS_CONFIG, data);
+ cxt.getContentResolver().update(SimInfo.CONTENT_URI, values,
+ SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID + "=" + subId, null);
+ }
+
+ /**
+ * load the config from siminfo db. It is only used internally.
+ */
+ public static @Nullable byte[] loadRcsConfigForSub(@NonNull Context cxt,
+ int subId, boolean isCompressed) {
+
+ byte[] data = null;
+
+ Cursor cursor = cxt.getContentResolver().query(SimInfo.CONTENT_URI, null,
+ SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID + "=" + subId, null, null);
+ try {
+ if (cursor != null && cursor.moveToFirst()) {
+ data = cursor.getBlob(cursor.getColumnIndexOrThrow(SimInfo.COLUMN_RCS_CONFIG));
+ }
+ } catch (Exception e) {
+ loge("error to load rcs config for sub:" + subId + " due to " + e);
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ return isCompressed ? data : decompressGzip(data);
+ }
+
+ /**
+ * {@link Parcelable#writeToParcel}
+ */
+ public void writeToParcel(@NonNull Parcel out, int flags) {
+ out.writeMap(mValues);
+ }
+
+ /**
+ * {@link Parcelable.Creator}
+ *
+ */
+ public static final @NonNull Parcelable.Creator<RcsConfig>
+ CREATOR = new Creator<RcsConfig>() {
+ @Override
+ public RcsConfig createFromParcel(Parcel in) {
+ HashMap<String, String> values = in.readHashMap(null);
+ return values == null ? null : new RcsConfig(values);
+ }
+
+ @Override
+ public RcsConfig[] newArray(int size) {
+ return new RcsConfig[size];
+ }
+ };
+
+ /**
+ * {@link Parcelable#describeContents}
+ */
+ public int describeContents() {
+ return 0;
+ }
+
+ private static void logd(String msg) {
+ Rlog.d(LOG_TAG, msg);
+ }
+
+ private static void loge(String msg) {
+ Rlog.e(LOG_TAG, msg);
+ }
+}
diff --git a/telephony/java/android/telephony/ims/aidl/IImsConfig.aidl b/telephony/java/android/telephony/ims/aidl/IImsConfig.aidl
index 57206c9f059a..5eee3890f1dc 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsConfig.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsConfig.aidl
@@ -18,8 +18,9 @@
package android.telephony.ims.aidl;
import android.os.PersistableBundle;
-
import android.telephony.ims.aidl.IImsConfigCallback;
+import android.telephony.ims.aidl.IRcsConfigCallback;
+import android.telephony.ims.RcsClientConfiguration;
import com.android.ims.ImsConfigListener;
@@ -41,4 +42,9 @@ interface IImsConfig {
int setConfigString(int item, String value);
void updateImsCarrierConfigs(in PersistableBundle bundle);
void notifyRcsAutoConfigurationReceived(in byte[] config, boolean isCompressed);
+ void notifyRcsAutoConfigurationRemoved();
+ void addRcsConfigCallback(IRcsConfigCallback c);
+ void removeRcsConfigCallback(IRcsConfigCallback c);
+ void triggerRcsReconfiguration();
+ void setRcsClientConfiguration(in RcsClientConfiguration rcc);
}
diff --git a/telephony/java/android/telephony/ims/aidl/IRcsConfigCallback.aidl b/telephony/java/android/telephony/ims/aidl/IRcsConfigCallback.aidl
new file mode 100644
index 000000000000..5a8973e37bce
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/IRcsConfigCallback.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims.aidl;
+
+/**
+ * The callback for RCS provisioning changes.
+ * {@hide}
+ */
+oneway interface IRcsConfigCallback {
+ void onConfigurationChanged(in byte[] config);
+ void onAutoConfigurationErrorReceived(int errorCode, String errorString);
+ void onConfigurationReset();
+ void onRemoved();
+}
+
diff --git a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
index e757d9f70ccc..cc050becfb25 100644
--- a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
@@ -23,8 +23,11 @@ import android.content.Context;
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.telephony.ims.ProvisioningManager;
+import android.telephony.ims.RcsClientConfiguration;
+import android.telephony.ims.RcsConfig;
import android.telephony.ims.aidl.IImsConfig;
import android.telephony.ims.aidl.IImsConfigCallback;
+import android.telephony.ims.aidl.IRcsConfigCallback;
import android.util.Log;
import com.android.ims.ImsConfig;
@@ -202,7 +205,13 @@ public class ImsConfigImplBase {
@Override
public void notifyRcsAutoConfigurationReceived(byte[] config, boolean isCompressed)
throws RemoteException {
- getImsConfigImpl().notifyRcsAutoConfigurationReceived(config, isCompressed);
+ getImsConfigImpl().onNotifyRcsAutoConfigurationReceived(config, isCompressed);
+ }
+
+ @Override
+ public void notifyRcsAutoConfigurationRemoved()
+ throws RemoteException {
+ getImsConfigImpl().onNotifyRcsAutoConfigurationRemoved();
}
private void notifyImsConfigChanged(int item, int value) throws RemoteException {
@@ -228,6 +237,26 @@ public class ImsConfigImplBase {
notifyImsConfigChanged(item, value);
}
}
+
+ @Override
+ public void addRcsConfigCallback(IRcsConfigCallback c) throws RemoteException {
+ getImsConfigImpl().addRcsConfigCallback(c);
+ }
+
+ @Override
+ public void removeRcsConfigCallback(IRcsConfigCallback c) throws RemoteException {
+ getImsConfigImpl().removeRcsConfigCallback(c);
+ }
+
+ @Override
+ public void triggerRcsReconfiguration() throws RemoteException {
+ getImsConfigImpl().triggerAutoConfiguration();
+ }
+
+ @Override
+ public void setRcsClientConfiguration(RcsClientConfiguration rcc) throws RemoteException {
+ getImsConfigImpl().setRcsClientConfiguration(rcc);
+ }
}
/**
@@ -257,6 +286,9 @@ public class ImsConfigImplBase {
private final RemoteCallbackListExt<IImsConfigCallback> mCallbacks =
new RemoteCallbackListExt<>();
+ private final RemoteCallbackListExt<IRcsConfigCallback> mRcsCallbacks =
+ new RemoteCallbackListExt<>();
+ private byte[] mRcsConfigData;
ImsConfigStub mImsConfigStub;
/**
@@ -320,6 +352,50 @@ public class ImsConfigImplBase {
});
}
+ private void addRcsConfigCallback(IRcsConfigCallback c) {
+ mRcsCallbacks.register(c);
+ if (mRcsConfigData != null) {
+ try {
+ c.onConfigurationChanged(mRcsConfigData);
+ } catch (RemoteException e) {
+ Log.w(TAG, "dead binder to call onConfigurationChanged, skipping.");
+ }
+ }
+ }
+
+ private void removeRcsConfigCallback(IRcsConfigCallback c) {
+ mRcsCallbacks.unregister(c);
+ }
+
+ private void onNotifyRcsAutoConfigurationReceived(byte[] config, boolean isCompressed) {
+ mRcsConfigData = isCompressed ? RcsConfig.decompressGzip(config) : config;
+ // can be null in testing
+ if (mRcsCallbacks != null) {
+ mRcsCallbacks.broadcastAction(c -> {
+ try {
+ c.onConfigurationChanged(mRcsConfigData);
+ } catch (RemoteException e) {
+ Log.w(TAG, "dead binder in notifyRcsAutoConfigurationReceived, skipping.");
+ }
+ });
+ }
+ notifyRcsAutoConfigurationReceived(config, isCompressed);
+ }
+
+ private void onNotifyRcsAutoConfigurationRemoved() {
+ mRcsConfigData = null;
+ if (mRcsCallbacks != null) {
+ mRcsCallbacks.broadcastAction(c -> {
+ try {
+ c.onConfigurationReset();
+ } catch (RemoteException e) {
+ Log.w(TAG, "dead binder in notifyRcsAutoConfigurationRemoved, skipping.");
+ }
+ });
+ }
+ notifyRcsAutoConfigurationRemoved();
+ }
+
/**
* @hide
*/
@@ -369,6 +445,12 @@ public class ImsConfigImplBase {
}
/**
+ * The RCS autoconfiguration XML file is removed or invalid.
+ */
+ public void notifyRcsAutoConfigurationRemoved() {
+ }
+
+ /**
* Sets the configuration value for this ImsService.
*
* @param item an integer key.
@@ -421,4 +503,43 @@ public class ImsConfigImplBase {
public void updateImsCarrierConfigs(PersistableBundle bundle) {
// Base Implementation - Should be overridden
}
+
+ /**
+ * Default messaging application parameters are sent to the ACS client
+ * using this interface.
+ * @param rcc RCS client configuration {@link RcsClientConfiguration}
+ */
+ public void setRcsClientConfiguration(@NonNull RcsClientConfiguration rcc) {
+ // Base Implementation - Should be overridden
+ }
+
+ /**
+ * Reconfiguration triggered by the RCS application. Most likely cause
+ * is the 403 forbidden to a SIP/HTTP request
+ */
+ public void triggerAutoConfiguration() {
+ // Base Implementation - Should be overridden
+ }
+
+ /**
+ * Errors during autoconfiguration connection setup are notified by the
+ * ACS client using this interface.
+ * @param errorCode HTTP error received during connection setup.
+ * @param errorString reason phrase received with the error
+ */
+ public final void notifyAutoConfigurationErrorReceived(int errorCode,
+ @NonNull String errorString) {
+ // can be null in testing
+ if (mRcsCallbacks == null) {
+ return;
+ }
+ mRcsCallbacks.broadcastAction(c -> {
+ try {
+ //TODO compressed by default?
+ c.onAutoConfigurationErrorReceived(errorCode, errorString);
+ } catch (RemoteException e) {
+ Log.w(TAG, "dead binder in notifyAutoConfigurationErrorReceived, skipping.");
+ }
+ });
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 205a425a5161..7c5047c2deaf 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -52,6 +52,7 @@ import android.telephony.SignalStrength;
import android.telephony.TelephonyHistogram;
import android.telephony.VisualVoicemailSmsFilterSettings;
import android.telephony.emergency.EmergencyNumber;
+import android.telephony.ims.RcsClientConfiguration;
import android.telephony.ims.aidl.IImsCapabilityCallback;
import android.telephony.ims.aidl.IImsConfig;
import android.telephony.ims.aidl.IImsConfigCallback;
@@ -59,6 +60,7 @@ import android.telephony.ims.aidl.IImsMmTelFeature;
import android.telephony.ims.aidl.IImsRcsFeature;
import android.telephony.ims.aidl.IImsRegistration;
import android.telephony.ims.aidl.IImsRegistrationCallback;
+import android.telephony.ims.aidl.IRcsConfigCallback;
import com.android.ims.internal.IImsServiceFeatureCallback;
import com.android.internal.telephony.CellNetworkScanResult;
import com.android.internal.telephony.IBooleanConsumer;
@@ -2303,4 +2305,51 @@ interface ITelephony {
* Return the release time for telephony to unbind GbaService.
*/
int getGbaReleaseTime(int subId);
+
+ /**
+ * Provide the client configuration parameters of the RCS application.
+ */
+ void setRcsClientConfiguration(int subId, in RcsClientConfiguration rcc);
+
+ /**
+ * return value to indicate whether the device and the carrier can support RCS VoLTE
+ * single registration.
+ */
+ boolean isRcsVolteSingleRegistrationCapable(int subId);
+
+ /**
+ * Register RCS provisioning callback.
+ */
+ void registerRcsProvisioningChangedCallback(int subId,
+ IRcsConfigCallback callback);
+
+ /**
+ * Unregister RCS provisioning callback.
+ */
+ void unregisterRcsProvisioningChangedCallback(int subId, IRcsConfigCallback callback);
+
+ /**
+ * trigger RCS reconfiguration.
+ */
+ void triggerRcsReconfiguration(int subId);
+
+ /**
+ * Overrides the config of RCS VoLTE single registration enabled for the device.
+ */
+ void setDeviceSingleRegistrationEnabledOverride(String enabled);
+
+ /**
+ * Gets the config of RCS VoLTE single registration enabled for the device.
+ */
+ boolean getDeviceSingleRegistrationEnabled();
+
+ /**
+ * Overrides the config of RCS VoLTE single registration enabled for the carrier/subscription.
+ */
+ boolean setCarrierSingleRegistrationEnabledOverride(int subId, String enabled);
+
+ /**
+ * Gets the config of RCS VoLTE single registration enabled for the carrier/subscription.
+ */
+ boolean getCarrierSingleRegistrationEnabled(int subId);
}