Merge "[RCS UCE] Expose the RCS UCE publishing device's capabilities APIs" am: 5b51530d0d

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1521659

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I9ccba700f145b722133b0e6929dca594ecef94b6
This commit is contained in:
James Lin
2021-01-13 00:41:12 +00:00
committed by Automerger Merge Worker
11 changed files with 613 additions and 204 deletions

View File

@@ -11570,7 +11570,32 @@ package android.telephony.ims {
} }
public class RcsUceAdapter { public class RcsUceAdapter {
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void addOnPublishStateChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RcsUceAdapter.OnPublishStateChangedListener) throws android.telephony.ims.ImsException;
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getUcePublishState() throws android.telephony.ims.ImsException;
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void removeOnPublishStateChangedListener(@NonNull android.telephony.ims.RcsUceAdapter.OnPublishStateChangedListener) throws android.telephony.ims.ImsException;
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUceSettingEnabled(boolean) throws android.telephony.ims.ImsException; method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUceSettingEnabled(boolean) throws android.telephony.ims.ImsException;
field public static final int CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED = 1; // 0x1
field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_2G = 7; // 0x7
field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_3G = 6; // 0x6
field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD = 4; // 0x4
field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_HSPAPLUS = 5; // 0x5
field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN = 9; // 0x9
field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED = 2; // 0x2
field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED = 3; // 0x3
field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_DISABLED = 10; // 0xa
field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_ENABLED = 11; // 0xb
field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN = 8; // 0x8
field public static final int CAPABILITY_UPDATE_TRIGGER_UNKNOWN = 0; // 0x0
field public static final int PUBLISH_STATE_NOT_PUBLISHED = 2; // 0x2
field public static final int PUBLISH_STATE_OK = 1; // 0x1
field public static final int PUBLISH_STATE_OTHER_ERROR = 6; // 0x6
field public static final int PUBLISH_STATE_RCS_PROVISION_ERROR = 4; // 0x4
field public static final int PUBLISH_STATE_REQUEST_TIMEOUT = 5; // 0x5
field public static final int PUBLISH_STATE_VOICE_PROVISION_ERROR = 3; // 0x3
}
public static interface RcsUceAdapter.OnPublishStateChangedListener {
method public void onPublishStateChange(int);
} }
public final class RtpHeaderExtension implements android.os.Parcelable { public final class RtpHeaderExtension implements android.os.Parcelable {
@@ -11777,16 +11802,24 @@ package android.telephony.ims.feature {
} }
public class RcsFeature extends android.telephony.ims.feature.ImsFeature { public class RcsFeature extends android.telephony.ims.feature.ImsFeature {
ctor public RcsFeature(); ctor @Deprecated public RcsFeature();
ctor public RcsFeature(@NonNull java.util.concurrent.Executor);
method public void changeEnabledCapabilities(@NonNull android.telephony.ims.feature.CapabilityChangeRequest, @NonNull android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy); method public void changeEnabledCapabilities(@NonNull android.telephony.ims.feature.CapabilityChangeRequest, @NonNull android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy);
method @NonNull public android.telephony.ims.stub.RcsCapabilityExchangeImplBase createCapabilityExchangeImpl(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.stub.CapabilityExchangeEventListener);
method public void onFeatureReady(); method public void onFeatureReady();
method public void onFeatureRemoved(); method public void onFeatureRemoved();
method public void removeCapabilityExchangeImpl(@NonNull android.telephony.ims.stub.RcsCapabilityExchangeImplBase);
} }
} }
package android.telephony.ims.stub { package android.telephony.ims.stub {
public interface CapabilityExchangeEventListener {
method public void onRequestPublishCapabilities(int) throws android.telephony.ims.ImsException;
method public void onUnpublish() throws android.telephony.ims.ImsException;
}
public interface DelegateConnectionMessageCallback { public interface DelegateConnectionMessageCallback {
method public void onMessageReceived(@NonNull android.telephony.ims.SipMessage); method public void onMessageReceived(@NonNull android.telephony.ims.SipMessage);
method public void onMessageSendFailure(@NonNull String, int); method public void onMessageSendFailure(@NonNull String, int);
@@ -11967,6 +12000,27 @@ package android.telephony.ims.stub {
method public int updateColr(int); method public int updateColr(int);
} }
public class RcsCapabilityExchangeImplBase {
ctor public RcsCapabilityExchangeImplBase(@NonNull java.util.concurrent.Executor);
method public void publishCapabilities(@NonNull String, @NonNull android.telephony.ims.stub.RcsCapabilityExchangeImplBase.PublishResponseCallback);
field public static final int COMMAND_CODE_FETCH_ERROR = 3; // 0x3
field public static final int COMMAND_CODE_GENERIC_FAILURE = 1; // 0x1
field public static final int COMMAND_CODE_INSUFFICIENT_MEMORY = 5; // 0x5
field public static final int COMMAND_CODE_INVALID_PARAM = 2; // 0x2
field public static final int COMMAND_CODE_LOST_NETWORK_CONNECTION = 6; // 0x6
field public static final int COMMAND_CODE_NOT_FOUND = 8; // 0x8
field public static final int COMMAND_CODE_NOT_SUPPORTED = 7; // 0x7
field public static final int COMMAND_CODE_NO_CHANGE = 10; // 0xa
field public static final int COMMAND_CODE_REQUEST_TIMEOUT = 4; // 0x4
field public static final int COMMAND_CODE_SERVICE_UNAVAILABLE = 9; // 0x9
field public static final int COMMAND_CODE_SERVICE_UNKNOWN = 0; // 0x0
}
public static interface RcsCapabilityExchangeImplBase.PublishResponseCallback {
method public void onCommandError(int) throws android.telephony.ims.ImsException;
method public void onNetworkResponse(@IntRange(from=100, to=699) int, @NonNull String) throws android.telephony.ims.ImsException;
}
public interface SipDelegate { public interface SipDelegate {
method public void closeDialog(@NonNull String); method public void closeDialog(@NonNull String);
method public void notifyMessageReceiveError(@NonNull String, int); method public void notifyMessageReceiveError(@NonNull String, int);

View File

@@ -34,7 +34,7 @@ import java.util.List;
* network during a SUBSCRIBE request. See RFC3863 for more information. * network during a SUBSCRIBE request. See RFC3863 for more information.
* @hide * @hide
*/ */
public class RcsContactPresenceTuple implements Parcelable { public final class RcsContactPresenceTuple implements Parcelable {
/** The service id of the MMTEL */ /** The service id of the MMTEL */
public static final String SERVICE_ID_MMTEL = "org.3gpp.urn:urn-7:3gpp-service.ims.icsi.mmtel"; public static final String SERVICE_ID_MMTEL = "org.3gpp.urn:urn-7:3gpp-service.ims.icsi.mmtel";
@@ -61,7 +61,7 @@ public class RcsContactPresenceTuple implements Parcelable {
* An optional addition to the PIDF Presence Tuple containing service capabilities, which is * An optional addition to the PIDF Presence Tuple containing service capabilities, which is
* defined in the servcaps element. See RFC5196, section 3.2.1. * defined in the servcaps element. See RFC5196, section 3.2.1.
*/ */
public static class ServiceCapabilities implements Parcelable { public static final class ServiceCapabilities implements Parcelable {
/** The service can simultaneously send and receive data. */ /** The service can simultaneously send and receive data. */
public static final String DUPLEX_MODE_FULL = "full"; public static final String DUPLEX_MODE_FULL = "full";
@@ -88,7 +88,7 @@ public class RcsContactPresenceTuple implements Parcelable {
/** /**
* Builder to help construct {@link ServiceCapabilities} instances. * Builder to help construct {@link ServiceCapabilities} instances.
*/ */
public static class Builder { public static final class Builder {
private ServiceCapabilities mCapabilities; private ServiceCapabilities mCapabilities;
@@ -106,7 +106,7 @@ public class RcsContactPresenceTuple implements Parcelable {
* Add the supported duplex mode. * Add the supported duplex mode.
* @param mode The supported duplex mode * @param mode The supported duplex mode
*/ */
public Builder addSupportedDuplexMode(@NonNull @DuplexMode String mode) { public @NonNull Builder addSupportedDuplexMode(@NonNull @DuplexMode String mode) {
mCapabilities.mSupportedDuplexModeList.add(mode); mCapabilities.mSupportedDuplexModeList.add(mode);
return this; return this;
} }
@@ -115,7 +115,7 @@ public class RcsContactPresenceTuple implements Parcelable {
* Add the unsupported duplex mode. * Add the unsupported duplex mode.
* @param mode The unsupported duplex mode * @param mode The unsupported duplex mode
*/ */
public Builder addUnsupportedDuplexMode(@NonNull @DuplexMode String mode) { public @NonNull Builder addUnsupportedDuplexMode(@NonNull @DuplexMode String mode) {
mCapabilities.mUnsupportedDuplexModeList.add(mode); mCapabilities.mUnsupportedDuplexModeList.add(mode);
return this; return this;
} }
@@ -123,7 +123,7 @@ public class RcsContactPresenceTuple implements Parcelable {
/** /**
* @return the ServiceCapabilities instance. * @return the ServiceCapabilities instance.
*/ */
public ServiceCapabilities build() { public @NonNull ServiceCapabilities build() {
return mCapabilities; return mCapabilities;
} }
} }
@@ -211,9 +211,9 @@ public class RcsContactPresenceTuple implements Parcelable {
/** /**
* Builder to help construct {@link RcsContactPresenceTuple} instances. * Builder to help construct {@link RcsContactPresenceTuple} instances.
*/ */
public static class Builder { public static final class Builder {
private RcsContactPresenceTuple mPresenceTuple; private final RcsContactPresenceTuple mPresenceTuple;
/** /**
* Builds a RcsContactPresenceTuple instance. * Builds a RcsContactPresenceTuple instance.
@@ -230,7 +230,7 @@ public class RcsContactPresenceTuple implements Parcelable {
/** /**
* The optional SIP Contact URI associated with the PIDF tuple element. * The optional SIP Contact URI associated with the PIDF tuple element.
*/ */
public Builder addContactUri(@NonNull Uri contactUri) { public @NonNull Builder addContactUri(@NonNull Uri contactUri) {
mPresenceTuple.mContactUri = contactUri; mPresenceTuple.mContactUri = contactUri;
return this; return this;
} }
@@ -239,7 +239,7 @@ public class RcsContactPresenceTuple implements Parcelable {
* The optional timestamp indicating the data and time of the status change of this tuple. * The optional timestamp indicating the data and time of the status change of this tuple.
* See RFC3863, section 4.1.7 for more information on the expected format. * See RFC3863, section 4.1.7 for more information on the expected format.
*/ */
public Builder addTimeStamp(@NonNull String timestamp) { public @NonNull Builder addTimeStamp(@NonNull String timestamp) {
mPresenceTuple.mTimestamp = timestamp; mPresenceTuple.mTimestamp = timestamp;
return this; return this;
} }
@@ -248,7 +248,7 @@ public class RcsContactPresenceTuple implements Parcelable {
* An optional parameter containing the description element of the service-description. See * An optional parameter containing the description element of the service-description. See
* OMA Presence SIMPLE specification v1.1 * OMA Presence SIMPLE specification v1.1
*/ */
public Builder addDescription(@NonNull String description) { public @NonNull Builder addDescription(@NonNull String description) {
mPresenceTuple.mServiceDescription = description; mPresenceTuple.mServiceDescription = description;
return this; return this;
} }
@@ -257,7 +257,7 @@ public class RcsContactPresenceTuple implements Parcelable {
* An optional parameter containing the service capabilities of the presence tuple if they * An optional parameter containing the service capabilities of the presence tuple if they
* are present in the servcaps element. * are present in the servcaps element.
*/ */
public Builder addServiceCapabilities(@NonNull ServiceCapabilities caps) { public @NonNull Builder addServiceCapabilities(@NonNull ServiceCapabilities caps) {
mPresenceTuple.mServiceCapabilities = caps; mPresenceTuple.mServiceCapabilities = caps;
return this; return this;
} }
@@ -265,7 +265,7 @@ public class RcsContactPresenceTuple implements Parcelable {
/** /**
* @return the constructed instance. * @return the constructed instance.
*/ */
public RcsContactPresenceTuple build() { public @NonNull RcsContactPresenceTuple build() {
return mPresenceTuple; return mPresenceTuple;
} }
} }

View File

@@ -144,7 +144,7 @@ public final class RcsContactUceCapability implements Parcelable {
* @param tag the supported feature tag * @param tag the supported feature tag
* @return this OptionBuilder * @return this OptionBuilder
*/ */
public @NonNull OptionsBuilder addFeatureTag(String tag) { public @NonNull OptionsBuilder addFeatureTag(@NonNull String tag) {
mCapabilities.mFeatureTags.add(tag); mCapabilities.mFeatureTags.add(tag);
return this; return this;
} }
@@ -154,7 +154,7 @@ public final class RcsContactUceCapability implements Parcelable {
* @param tags the list of the supported feature tags * @param tags the list of the supported feature tags
* @return this OptionBuilder * @return this OptionBuilder
*/ */
public @NonNull OptionsBuilder addFeatureTags(List<String> tags) { public @NonNull OptionsBuilder addFeatureTags(@NonNull List<String> tags) {
mCapabilities.mFeatureTags.addAll(tags); mCapabilities.mFeatureTags.addAll(tags);
return this; return this;
} }
@@ -195,7 +195,7 @@ public final class RcsContactUceCapability implements Parcelable {
* @param tuple The {@link RcsContactPresenceTuple} to be added into. * @param tuple The {@link RcsContactPresenceTuple} to be added into.
* @return this PresenceBuilder * @return this PresenceBuilder
*/ */
public @NonNull PresenceBuilder addCapabilityTuple(RcsContactPresenceTuple tuple) { public @NonNull PresenceBuilder addCapabilityTuple(@NonNull RcsContactPresenceTuple tuple) {
mCapabilities.mPresenceTuples.add(tuple); mCapabilities.mPresenceTuples.add(tuple);
return this; return this;
} }
@@ -205,7 +205,8 @@ public final class RcsContactUceCapability implements Parcelable {
* @param tuples The list of the {@link RcsContactPresenceTuple} to be added into. * @param tuples The list of the {@link RcsContactPresenceTuple} to be added into.
* @return this PresenceBuilder * @return this PresenceBuilder
*/ */
public @NonNull PresenceBuilder addCapabilityTuples(List<RcsContactPresenceTuple> tuples) { public @NonNull PresenceBuilder addCapabilityTuples(
@NonNull List<RcsContactPresenceTuple> tuples) {
mCapabilities.mPresenceTuples.addAll(tuples); mCapabilities.mPresenceTuples.addAll(tuples);
return this; return this;
} }
@@ -282,7 +283,7 @@ public final class RcsContactUceCapability implements Parcelable {
* @return The feature tags present in the OPTIONS response from the network. * @return The feature tags present in the OPTIONS response from the network.
* <p> * <p>
* Note: this is only populated if {@link #getCapabilityMechanism} is * Note: this is only populated if {@link #getCapabilityMechanism} is
* {@link CAPABILITY_MECHANISM_OPTIONS} * {@link RcsContactUceCapability#CAPABILITY_MECHANISM_OPTIONS}
*/ */
public @NonNull List<String> getOptionsFeatureTags() { public @NonNull List<String> getOptionsFeatureTags() {
if (mCapabilityMechanism != CAPABILITY_MECHANISM_OPTIONS) { if (mCapabilityMechanism != CAPABILITY_MECHANISM_OPTIONS) {
@@ -296,7 +297,7 @@ public final class RcsContactUceCapability implements Parcelable {
* contained in the NOTIFY response from the network. * contained in the NOTIFY response from the network.
* <p> * <p>
* Note: this is only populated if {@link #getCapabilityMechanism} is * Note: this is only populated if {@link #getCapabilityMechanism} is
* {@link CAPABILITY_MECHANISM_PRESENCE} * {@link RcsContactUceCapability#CAPABILITY_MECHANISM_PRESENCE}
*/ */
public @NonNull List<RcsContactPresenceTuple> getPresenceTuples() { public @NonNull List<RcsContactPresenceTuple> getPresenceTuples() {
if (mCapabilityMechanism != CAPABILITY_MECHANISM_PRESENCE) { if (mCapabilityMechanism != CAPABILITY_MECHANISM_PRESENCE) {
@@ -312,9 +313,9 @@ public final class RcsContactUceCapability implements Parcelable {
* *
* <p> * <p>
* Note: this is only populated if {@link #getCapabilityMechanism} is * Note: this is only populated if {@link #getCapabilityMechanism} is
* {@link CAPABILITY_MECHANISM_PRESENCE} * {@link RcsContactUceCapability#CAPABILITY_MECHANISM_PRESENCE}
*/ */
public @Nullable RcsContactPresenceTuple getPresenceTuple(String serviceId) { public @Nullable RcsContactPresenceTuple getPresenceTuple(@NonNull String serviceId) {
if (mCapabilityMechanism != CAPABILITY_MECHANISM_PRESENCE) { if (mCapabilityMechanism != CAPABILITY_MECHANISM_PRESENCE) {
return null; return null;
} }

View File

@@ -36,7 +36,9 @@ import android.util.Log;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
/** /**
@@ -110,7 +112,7 @@ public class RcsUceAdapter {
public static final int ERROR_FORBIDDEN = 6; public static final int ERROR_FORBIDDEN = 6;
/** /**
* The contact URI requested is not provisioned for VoLTE or it is not known as an IMS * The contact URI requested is not provisioned for voice or it is not known as an IMS
* subscriber to the carrier network. * subscriber to the carrier network.
* @hide * @hide
*/ */
@@ -128,26 +130,26 @@ public class RcsUceAdapter {
* The network did not respond to the capabilities request before the request timed out. * The network did not respond to the capabilities request before the request timed out.
* @hide * @hide
*/ */
public static final int ERROR_REQUEST_TIMEOUT = 10; public static final int ERROR_REQUEST_TIMEOUT = 9;
/** /**
* The request failed due to the service having insufficient memory. * The request failed due to the service having insufficient memory.
* @hide * @hide
*/ */
public static final int ERROR_INSUFFICIENT_MEMORY = 11; public static final int ERROR_INSUFFICIENT_MEMORY = 10;
/** /**
* The network was lost while trying to complete the request. * The network was lost while trying to complete the request.
* @hide * @hide
*/ */
public static final int ERROR_LOST_NETWORK = 12; public static final int ERROR_LOST_NETWORK = 11;
/** /**
* The network is temporarily unavailable or busy. Retries should only be done after the retry * The network is temporarily unavailable or busy. Retries should only be done after the retry
* time returned in {@link CapabilitiesCallback#onError} has elapsed. * time returned in {@link CapabilitiesCallback#onError} has elapsed.
* @hide * @hide
*/ */
public static final int ERROR_SERVER_UNAVAILABLE = 13; public static final int ERROR_SERVER_UNAVAILABLE = 12;
/**@hide*/ /**@hide*/
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@@ -167,70 +169,94 @@ public class RcsUceAdapter {
}) })
public @interface ErrorCode {} public @interface ErrorCode {}
/**
* A capability update has been requested but the reason is unknown.
* @hide
*/
@SystemApi
public static final int CAPABILITY_UPDATE_TRIGGER_UNKNOWN = 0;
/** /**
* A capability update has been requested due to the Entity Tag (ETag) expiring. * A capability update has been requested due to the Entity Tag (ETag) expiring.
* @hide * @hide
*/ */
public static final int CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED = 0; @SystemApi
public static final int CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED = 1;
/** /**
* A capability update has been requested due to moving to LTE with VoPS disabled. * A capability update has been requested due to moving to LTE with VoPS disabled.
* @hide * @hide
*/ */
public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED = 1; @SystemApi
public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED = 2;
/** /**
* A capability update has been requested due to moving to LTE with VoPS enabled. * A capability update has been requested due to moving to LTE with VoPS enabled.
* @hide * @hide
*/ */
public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED = 2; @SystemApi
public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED = 3;
/** /**
* A capability update has been requested due to moving to eHRPD. * A capability update has been requested due to moving to eHRPD.
* @hide * @hide
*/ */
public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD = 3; @SystemApi
public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD = 4;
/** /**
* A capability update has been requested due to moving to HSPA+. * A capability update has been requested due to moving to HSPA+.
* @hide * @hide
*/ */
public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_HSPAPLUS = 4; @SystemApi
public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_HSPAPLUS = 5;
/** /**
* A capability update has been requested due to moving to 3G. * A capability update has been requested due to moving to 3G.
* @hide * @hide
*/ */
public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_3G = 5; @SystemApi
public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_3G = 6;
/** /**
* A capability update has been requested due to moving to 2G. * A capability update has been requested due to moving to 2G.
* @hide * @hide
*/ */
public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_2G = 6; @SystemApi
public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_2G = 7;
/** /**
* A capability update has been requested due to moving to WLAN * A capability update has been requested due to moving to WLAN
* @hide * @hide
*/ */
public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN = 7; @SystemApi
public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN = 8;
/** /**
* A capability update has been requested due to moving to IWLAN * A capability update has been requested due to moving to IWLAN
* @hide * @hide
*/ */
public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN = 8; @SystemApi
/** public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN = 9;
* A capability update has been requested but the reason is unknown.
* @hide
*/
public static final int CAPABILITY_UPDATE_TRIGGER_UNKNOWN = 9;
/** /**
* A capability update has been requested due to moving to 5G NR with VoPS disabled. * A capability update has been requested due to moving to 5G NR with VoPS disabled.
* @hide * @hide
*/ */
@SystemApi
public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_DISABLED = 10; public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_DISABLED = 10;
/** /**
* A capability update has been requested due to moving to 5G NR with VoPS enabled. * A capability update has been requested due to moving to 5G NR with VoPS enabled.
* @hide * @hide
*/ */
@SystemApi
public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_ENABLED = 11; public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_ENABLED = 11;
/**@hide*/ /**@hide*/
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = "ERROR_", value = { @IntDef(prefix = "ERROR_", value = {
CAPABILITY_UPDATE_TRIGGER_UNKNOWN,
CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED, CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED,
CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED, CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED,
CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED, CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED,
@@ -240,7 +266,6 @@ public class RcsUceAdapter {
CAPABILITY_UPDATE_TRIGGER_MOVE_TO_2G, CAPABILITY_UPDATE_TRIGGER_MOVE_TO_2G,
CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN, CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN,
CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN, CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN,
CAPABILITY_UPDATE_TRIGGER_UNKNOWN,
CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_DISABLED, CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_DISABLED,
CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_ENABLED CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_ENABLED
}) })
@@ -251,32 +276,37 @@ public class RcsUceAdapter {
* UCE. * UCE.
* @hide * @hide
*/ */
@SystemApi
public static final int PUBLISH_STATE_OK = 1; public static final int PUBLISH_STATE_OK = 1;
/** /**
* The hasn't published its capabilities since boot or hasn't gotten any publish response yet. * The hasn't published its capabilities since boot or hasn't gotten any publish response yet.
* @hide * @hide
*/ */
@SystemApi
public static final int PUBLISH_STATE_NOT_PUBLISHED = 2; public static final int PUBLISH_STATE_NOT_PUBLISHED = 2;
/** /**
* The device has tried to publish its capabilities, which has resulted in an error. This error * The device has tried to publish its capabilities, which has resulted in an error. This error
* is related to the fact that the device is not VoLTE provisioned. * is related to the fact that the device is not provisioned for voice.
* @hide * @hide
*/ */
public static final int PUBLISH_STATE_VOLTE_PROVISION_ERROR = 3; @SystemApi
public static final int PUBLISH_STATE_VOICE_PROVISION_ERROR = 3;
/** /**
* The device has tried to publish its capabilities, which has resulted in an error. This error * The device has tried to publish its capabilities, which has resulted in an error. This error
* is related to the fact that the device is not RCS or UCE provisioned. * is related to the fact that the device is not RCS or UCE provisioned.
* @hide * @hide
*/ */
@SystemApi
public static final int PUBLISH_STATE_RCS_PROVISION_ERROR = 4; public static final int PUBLISH_STATE_RCS_PROVISION_ERROR = 4;
/** /**
* The last publish resulted in a "408 Request Timeout" response. * The last publish resulted in a "408 Request Timeout" response.
* @hide * @hide
*/ */
@SystemApi
public static final int PUBLISH_STATE_REQUEST_TIMEOUT = 5; public static final int PUBLISH_STATE_REQUEST_TIMEOUT = 5;
/** /**
@@ -286,6 +316,7 @@ public class RcsUceAdapter {
* Device shall retry with exponential back-off. * Device shall retry with exponential back-off.
* @hide * @hide
*/ */
@SystemApi
public static final int PUBLISH_STATE_OTHER_ERROR = 6; public static final int PUBLISH_STATE_OTHER_ERROR = 6;
/**@hide*/ /**@hide*/
@@ -293,7 +324,7 @@ public class RcsUceAdapter {
@IntDef(prefix = "PUBLISH_STATE_", value = { @IntDef(prefix = "PUBLISH_STATE_", value = {
PUBLISH_STATE_OK, PUBLISH_STATE_OK,
PUBLISH_STATE_NOT_PUBLISHED, PUBLISH_STATE_NOT_PUBLISHED,
PUBLISH_STATE_VOLTE_PROVISION_ERROR, PUBLISH_STATE_VOICE_PROVISION_ERROR,
PUBLISH_STATE_RCS_PROVISION_ERROR, PUBLISH_STATE_RCS_PROVISION_ERROR,
PUBLISH_STATE_REQUEST_TIMEOUT, PUBLISH_STATE_REQUEST_TIMEOUT,
PUBLISH_STATE_OTHER_ERROR PUBLISH_STATE_OTHER_ERROR
@@ -301,55 +332,61 @@ public class RcsUceAdapter {
public @interface PublishState {} public @interface PublishState {}
/** /**
* An application can use {@link #registerPublishStateCallback} to register a * An application can use {@link #addOnPublishStateChangedListener} to register a
* {@link PublishStateCallback), which will notify the user when the publish state to the * {@link OnPublishStateChangedListener ), which will notify the user when the publish state to
* network changes. * the network changes.
* @hide * @hide
*/ */
public static class PublishStateCallback { @SystemApi
public interface OnPublishStateChangedListener {
private static class PublishStateBinder extends IRcsUcePublishStateCallback.Stub {
private final PublishStateCallback mLocalCallback;
private Executor mExecutor;
PublishStateBinder(PublishStateCallback c) {
mLocalCallback = c;
}
@Override
public void onPublishStateChanged(int publishState) {
if (mLocalCallback == null) return;
final long callingIdentity = Binder.clearCallingIdentity();
try {
mExecutor.execute(() -> mLocalCallback.onChanged(publishState));
} finally {
restoreCallingIdentity(callingIdentity);
}
}
private void setExecutor(Executor executor) {
mExecutor = executor;
}
}
private final PublishStateBinder mBinder = new PublishStateBinder(this);
/**@hide*/
public final IRcsUcePublishStateCallback getBinder() {
return mBinder;
}
private void setExecutor(Executor executor) {
mBinder.setExecutor(executor);
}
/** /**
* Notifies the callback when the publish state has changed. * Notifies the callback when the publish state has changed.
* @param publishState The latest update to the publish state. * @param publishState The latest update to the publish state.
*/ */
public void onChanged(@PublishState int publishState) { void onPublishStateChange(@PublishState int publishState);
}
/**
* An application can use {@link #addOnPublishStateChangedListener} to register a
* {@link OnPublishStateChangedListener ), which will notify the user when the publish state to
* the network changes.
* @hide
*/
public static class PublishStateCallbackAdapter {
private static class PublishStateBinder extends IRcsUcePublishStateCallback.Stub {
private final OnPublishStateChangedListener mPublishStateChangeListener;
private final Executor mExecutor;
PublishStateBinder(Executor executor, OnPublishStateChangedListener listener) {
mExecutor = executor;
mPublishStateChangeListener = listener;
}
@Override
public void onPublishStateChanged(int publishState) {
if (mPublishStateChangeListener == null) return;
final long callingIdentity = Binder.clearCallingIdentity();
try {
mExecutor.execute(() ->
mPublishStateChangeListener.onPublishStateChange(publishState));
} finally {
restoreCallingIdentity(callingIdentity);
}
}
}
private final PublishStateBinder mBinder;
public PublishStateCallbackAdapter(@NonNull Executor executor,
@NonNull OnPublishStateChangedListener listener) {
mBinder = new PublishStateBinder(executor, listener);
}
/**@hide*/
public final IRcsUcePublishStateCallback getBinder() {
return mBinder;
} }
} }
@@ -395,6 +432,8 @@ public class RcsUceAdapter {
private final Context mContext; private final Context mContext;
private final int mSubId; private final int mSubId;
private final Map<OnPublishStateChangedListener, PublishStateCallbackAdapter>
mPublishStateCallbacks;
/** /**
* Not to be instantiated directly, use {@link ImsRcsManager#getUceAdapter()} to instantiate * Not to be instantiated directly, use {@link ImsRcsManager#getUceAdapter()} to instantiate
@@ -404,6 +443,7 @@ public class RcsUceAdapter {
RcsUceAdapter(Context context, int subId) { RcsUceAdapter(Context context, int subId) {
mContext = context; mContext = context;
mSubId = subId; mSubId = subId;
mPublishStateCallbacks = new HashMap<>();
} }
/** /**
@@ -588,6 +628,7 @@ public class RcsUceAdapter {
* becomes inactive. See {@link ImsException#getCode()} for more information on the error codes. * becomes inactive. See {@link ImsException#getCode()} for more information on the error codes.
* @hide * @hide
*/ */
@SystemApi
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public @PublishState int getUcePublishState() throws ImsException { public @PublishState int getUcePublishState() throws ImsException {
IImsRcsController imsRcsController = getIImsRcsController(); IImsRcsController imsRcsController = getIImsRcsController();
@@ -609,81 +650,90 @@ public class RcsUceAdapter {
} }
/** /**
* Registers a {@link PublishStateCallback} with the system, which will provide publish state * Registers a {@link OnPublishStateChangedListener} with the system, which will provide publish
* updates for the subscription specified in {@link ImsManager@getRcsManager(subid)}. * state updates for the subscription specified in {@link ImsManager@getRcsManager(subid)}.
* <p> * <p>
* Use {@link SubscriptionManager.OnSubscriptionsChangedListener} to listen to subscription * Use {@link SubscriptionManager.OnSubscriptionsChangedListener} to listen to subscription
* changed events and call {@link #unregisterPublishStateCallback} to clean up. * changed events and call {@link #unregisterPublishStateCallback} to clean up.
* <p> * <p>
* The registered {@link PublishStateCallback} will also receive a callback when it is * The registered {@link OnPublishStateChangedListener} will also receive a callback when it is
* registered with the current publish state. * registered with the current publish state.
* *
* @param executor The executor the listener callback events should be run on. * @param executor The executor the listener callback events should be run on.
* @param c The {@link PublishStateCallback} to be added. * @param listener The {@link OnPublishStateChangedListener} to be added.
* @throws ImsException if the subscription associated with this callback is valid, but * @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 {@link ImsService} associated with the subscription is not available. This can happen if
* the service crashed, for example. See {@link ImsException#getCode()} for a more detailed * the service crashed, for example. See {@link ImsException#getCode()} for a more detailed
* reason. * reason.
* @hide * @hide
*/ */
@SystemApi
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public void registerPublishStateCallback(@NonNull @CallbackExecutor Executor executor, public void addOnPublishStateChangedListener(@NonNull @CallbackExecutor Executor executor,
@NonNull PublishStateCallback c) throws ImsException { @NonNull OnPublishStateChangedListener listener) throws ImsException {
if (c == null) {
throw new IllegalArgumentException("Must include a non-null PublishStateCallback.");
}
if (executor == null) { if (executor == null) {
throw new IllegalArgumentException("Must include a non-null Executor."); throw new IllegalArgumentException("Must include a non-null Executor.");
} }
if (listener == null) {
throw new IllegalArgumentException(
"Must include a non-null OnPublishStateChangedListener.");
}
IImsRcsController imsRcsController = getIImsRcsController(); IImsRcsController imsRcsController = getIImsRcsController();
if (imsRcsController == null) { if (imsRcsController == null) {
Log.e(TAG, "registerPublishStateCallback : IImsRcsController is null"); Log.e(TAG, "addOnPublishStateChangedListener : IImsRcsController is null");
throw new ImsException("Cannot find remote IMS service", throw new ImsException("Cannot find remote IMS service",
ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
} }
c.setExecutor(executor); PublishStateCallbackAdapter stateCallback = addPublishStateCallback(executor, listener);
try { try {
imsRcsController.registerUcePublishStateCallback(mSubId, c.getBinder()); imsRcsController.registerUcePublishStateCallback(mSubId, stateCallback.getBinder());
} catch (ServiceSpecificException e) { } catch (ServiceSpecificException e) {
throw new ImsException(e.getMessage(), e.errorCode); throw new ImsException(e.getMessage(), e.errorCode);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "Error calling IImsRcsController#registerUcePublishStateCallback", e); Log.e(TAG, "Error calling IImsRcsController#registerUcePublishStateCallback", e);
throw new ImsException("Remote IMS Service is not available", throw new ImsException("Remote IMS Service is not available",
ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
} }
} }
/** /**
* Removes an existing {@link PublishStateCallback}. * Removes an existing {@link OnPublishStateChangedListener}.
* <p> * <p>
* When the subscription associated with this callback is removed * When the subscription associated with this callback is removed
* (SIM removed, ESIM swap,etc...), this callback will automatically be removed. If this method * (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. * is called for an inactive subscription, it will result in a no-op.
* *
* @param c The callback to be unregistered. * @param listener The callback to be unregistered.
* @throws ImsException if the subscription associated with this callback is valid, but * @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 {@link ImsService} associated with the subscription is not available. This can happen if
* the service crashed, for example. See {@link ImsException#getCode()} for a more detailed * the service crashed, for example. See {@link ImsException#getCode()} for a more detailed
* reason. * reason.
* @hide * @hide
*/ */
@SystemApi
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public void unregisterPublishStateCallback(@NonNull PublishStateCallback c) public void removeOnPublishStateChangedListener(
throws ImsException { @NonNull OnPublishStateChangedListener listener) throws ImsException {
if (c == null) { if (listener == null) {
throw new IllegalArgumentException("Must include a non-null PublishStateCallback."); throw new IllegalArgumentException(
"Must include a non-null OnPublishStateChangedListener.");
} }
IImsRcsController imsRcsController = getIImsRcsController(); IImsRcsController imsRcsController = getIImsRcsController();
if (imsRcsController == null) { if (imsRcsController == null) {
Log.e(TAG, "unregisterPublishStateCallback: IImsRcsController is null"); Log.e(TAG, "removeOnPublishStateChangedListener: IImsRcsController is null");
throw new ImsException("Cannot find remote IMS service", throw new ImsException("Cannot find remote IMS service",
ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
} }
PublishStateCallbackAdapter callback = removePublishStateCallback(listener);
if (callback == null) {
return;
}
try { try {
imsRcsController.unregisterUcePublishStateCallback(mSubId, c.getBinder()); imsRcsController.unregisterUcePublishStateCallback(mSubId, callback.getBinder());
} catch (android.os.ServiceSpecificException e) { } catch (android.os.ServiceSpecificException e) {
throw new ImsException(e.getMessage(), e.errorCode); throw new ImsException(e.getMessage(), e.errorCode);
} catch (RemoteException e) { } catch (RemoteException e) {
@@ -763,6 +813,36 @@ public class RcsUceAdapter {
} }
} }
/**
* Add the {@link OnPublishStateChangedListener} to collection for tracking.
* @param executor The executor that will be used when the publish state is changed and the
* {@link OnPublishStateChangedListener} is called.
* @param listener The {@link OnPublishStateChangedListener} to call the publish state changed.
* @return The {@link PublishStateCallbackAdapter} to wrapper the
* {@link OnPublishStateChangedListener}
*/
private PublishStateCallbackAdapter addPublishStateCallback(@NonNull Executor executor,
@NonNull OnPublishStateChangedListener listener) {
PublishStateCallbackAdapter adapter = new PublishStateCallbackAdapter(executor, listener);
synchronized (mPublishStateCallbacks) {
mPublishStateCallbacks.put(listener, adapter);
}
return adapter;
}
/**
* Remove the existing {@link OnPublishStateChangedListener}.
* @param listener The {@link OnPublishStateChangedListener} to remove from the collection.
* @return The wrapper class {@link PublishStateCallbackAdapter} associated with the
* {@link OnPublishStateChangedListener}.
*/
private PublishStateCallbackAdapter removePublishStateCallback(
@NonNull OnPublishStateChangedListener listener) {
synchronized (mPublishStateCallbacks) {
return mPublishStateCallbacks.remove(listener);
}
}
private IImsRcsController getIImsRcsController() { private IImsRcsController getIImsRcsController() {
IBinder binder = TelephonyFrameworkInitializer IBinder binder = TelephonyFrameworkInitializer
.getTelephonyServiceManager() .getTelephonyServiceManager()

View File

@@ -0,0 +1,115 @@
/*
* 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;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.net.Uri;
import android.os.Binder;
import android.os.RemoteException;
import android.telephony.ims.RcsContactUceCapability;
import android.telephony.ims.stub.CapabilityExchangeEventListener;
import android.util.Log;
import java.util.List;
/**
* The ICapabilityExchangeEventListener wrapper class to store the listener which is registered by
* the framework. This wrapper class also delivers the request to the framework when receive the
* request from the network.
* @hide
*/
public class CapabilityExchangeAidlWrapper implements CapabilityExchangeEventListener {
private static final String LOG_TAG = "CapExchangeListener";
private final ICapabilityExchangeEventListener mListenerBinder;
public CapabilityExchangeAidlWrapper(@Nullable ICapabilityExchangeEventListener listener) {
mListenerBinder = listener;
}
/**
* Receives the request of publishing capabilities from the network and deliver this request
* to the framework via the registered capability exchange event listener.
*/
public void onRequestPublishCapabilities(int publishTriggerType) {
ICapabilityExchangeEventListener listener = mListenerBinder;
if (listener == null) {
return;
}
try {
listener.onRequestPublishCapabilities(publishTriggerType);
} catch (RemoteException e) {
Log.w(LOG_TAG, "request publish capabilities exception: " + e);
}
}
/**
* Receives the unpublish notification and deliver this callback to the framework.
*/
public void onUnpublish() {
ICapabilityExchangeEventListener listener = mListenerBinder;
if (listener == null) {
return;
}
try {
listener.onUnpublish();
} catch (RemoteException e) {
Log.w(LOG_TAG, "Unpublish exception: " + e);
}
}
/**
* Receives the callback of the remote capability request from the network and deliver this
* request to the framework.
*/
public void onRemoteCapabilityRequest(@NonNull Uri contactUri,
@NonNull List<String> remoteCapabilities, @NonNull OptionsRequestCallback callback) {
ICapabilityExchangeEventListener listener = mListenerBinder;
if (listener == null) {
return;
}
IOptionsRequestCallback internalCallback = new IOptionsRequestCallback.Stub() {
@Override
public void respondToCapabilityRequest(RcsContactUceCapability ownCapabilities) {
final long callingIdentity = Binder.clearCallingIdentity();
try {
callback.onRespondToCapabilityRequest(ownCapabilities);
} finally {
restoreCallingIdentity(callingIdentity);
}
}
@Override
public void respondToCapabilityRequestWithError(int code, String reason) {
final long callingIdentity = Binder.clearCallingIdentity();
try {
callback.onRespondToCapabilityRequestWithError(code, reason);
} finally {
restoreCallingIdentity(callingIdentity);
}
}
};
try {
listener.onRemoteCapabilityRequest(contactUri, remoteCapabilities, internalCallback);
} catch (RemoteException e) {
Log.w(LOG_TAG, "Remote capability request exception: " + e);
}
}
}

View File

@@ -22,54 +22,15 @@ import android.telephony.ims.aidl.IOptionsRequestCallback;
import java.util.List; import java.util.List;
/** /**
* Listener interface for the ImsService to use to notify the framework of UCE events. * Listener interface for the ImsService to use to notify the framework of UCE
* events.
*
* See CapabilityExchangeEventListener for more information.
* {@hide} * {@hide}
*/ */
oneway interface ICapabilityExchangeEventListener { oneway interface ICapabilityExchangeEventListener {
/**
* Trigger the framework to provide a capability update using
* {@link RcsCapabilityExchangeImplBase#publishCapabilities}.
* <p>
* This is typically used when trying to generate an initial PUBLISH for a new
* subscription to the network. The device will cache all presence publications
* after boot until this method is called the first time.
* @param publishTriggerType {@link StackPublishTriggerType} The reason for the
* capability update request.
* @throws ImsException If this {@link RcsPresenceExchangeImplBase} instance is
* not currently connected to the framework. This can happen if the
* {@link RcsFeature} is not {@link ImsFeature#STATE_READY} and the
* {@link RcsFeature} has not received the
* {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare
* cases when the Telephony stack has crashed.
*/
void onRequestPublishCapabilities(int publishTriggerType); void onRequestPublishCapabilities(int publishTriggerType);
/**
* Notify the framework that the device's capabilities have been unpublished from the network.
*
* @throws ImsException If this {@link RcsPresenceExchangeImplBase} instance is not currently
* connected to the framework. This can happen if the {@link RcsFeature} is not
* {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received the
* {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases when the
* Telephony stack has crashed.
*/
void onUnpublish(); void onUnpublish();
/**
* Inform the framework of a query for this device's UCE capabilities.
* <p>
* The framework will respond via the
* {@link IOptionsRequestCallback#respondToCapabilityRequest} or
* {@link IOptionsRequestCallback#respondToCapabilityRequestWithError} method.
* @param contactUri The URI associated with the remote contact that is requesting capabilities.
* @param remoteCapabilities The remote contact's capability information.
* @throws ImsException If this {@link RcsSipOptionsImplBase} instance is not currently
* connected to the framework. This can happen if the {@link RcsFeature} is not
* {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received
* the {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases when
* the Telephony stack has crashed.
*/
void onRemoteCapabilityRequest(in Uri contactUri, void onRemoteCapabilityRequest(in Uri contactUri,
in List<String> remoteCapabilities, in List<String> remoteCapabilities, IOptionsRequestCallback cb);
IOptionsRequestCallback cb);
} }

View File

@@ -33,7 +33,6 @@ oneway interface IOptionsRequestCallback {
/** /**
* Respond to a remote capability request from the contact specified with the * Respond to a remote capability request from the contact specified with the
* specified error. * specified error.
* @param contactUri A URI containing the remote contact.
* @param code The SIP response code to respond with. * @param code The SIP response code to respond with.
* @param reason A non-null String containing the reason associated with the SIP code. * @param reason A non-null String containing the reason associated with the SIP code.
*/ */

View File

@@ -336,7 +336,7 @@ public abstract class ImsFeature {
/** /**
* @hide * @hide
*/ */
public final void initialize(Context context, int slotId) { public void initialize(Context context, int slotId) {
mContext = context; mContext = context;
mSlotId = slotId; mSlotId = slotId;
} }

View File

@@ -21,9 +21,11 @@ import android.annotation.IntDef;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.annotation.SystemApi; import android.annotation.SystemApi;
import android.content.Context;
import android.net.Uri; import android.net.Uri;
import android.os.RemoteException; import android.os.RemoteException;
import android.telephony.ims.RcsUceAdapter; import android.telephony.ims.RcsUceAdapter;
import android.telephony.ims.aidl.CapabilityExchangeAidlWrapper;
import android.telephony.ims.aidl.ICapabilityExchangeEventListener; import android.telephony.ims.aidl.ICapabilityExchangeEventListener;
import android.telephony.ims.aidl.IImsCapabilityCallback; import android.telephony.ims.aidl.IImsCapabilityCallback;
import android.telephony.ims.aidl.IImsRcsFeature; import android.telephony.ims.aidl.IImsRcsFeature;
@@ -33,6 +35,7 @@ import android.telephony.ims.aidl.ISubscribeResponseCallback;
import android.telephony.ims.aidl.RcsOptionsResponseAidlWrapper; import android.telephony.ims.aidl.RcsOptionsResponseAidlWrapper;
import android.telephony.ims.aidl.RcsPublishResponseAidlWrapper; import android.telephony.ims.aidl.RcsPublishResponseAidlWrapper;
import android.telephony.ims.aidl.RcsSubscribeResponseAidlWrapper; import android.telephony.ims.aidl.RcsSubscribeResponseAidlWrapper;
import android.telephony.ims.stub.CapabilityExchangeEventListener;
import android.telephony.ims.stub.ImsRegistrationImplBase; import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.telephony.ims.stub.RcsCapabilityExchangeImplBase; import android.telephony.ims.stub.RcsCapabilityExchangeImplBase;
import android.telephony.ims.stub.RcsCapabilityExchangeImplBase.OptionsResponseCallback; import android.telephony.ims.stub.RcsCapabilityExchangeImplBase.OptionsResponseCallback;
@@ -114,8 +117,10 @@ public class RcsFeature extends ImsFeature {
@Override @Override
public void setCapabilityExchangeEventListener( public void setCapabilityExchangeEventListener(
@Nullable ICapabilityExchangeEventListener listener) throws RemoteException { @Nullable ICapabilityExchangeEventListener listener) throws RemoteException {
executeMethodAsync(() -> mReference.setCapabilityExchangeEventListener(listener), CapabilityExchangeEventListener listenerWrapper =
"setCapabilityExchangeEventListener"); new CapabilityExchangeAidlWrapper(listener);
executeMethodAsync(() -> mReference.setCapabilityExchangeEventListener(
mExecutor, listenerWrapper), "setCapabilityExchangeEventListener");
} }
@Override @Override
@@ -245,9 +250,10 @@ public class RcsFeature extends ImsFeature {
} }
} }
private final Executor mExecutor;
private final RcsFeatureBinder mImsRcsBinder; private final RcsFeatureBinder mImsRcsBinder;
private RcsCapabilityExchangeImplBase mCapabilityExchangeImpl; private RcsCapabilityExchangeImplBase mCapabilityExchangeImpl;
private ICapabilityExchangeEventListener mCapExchangeEventListener; private CapabilityExchangeEventListener mCapExchangeEventListener;
/** /**
* Create a new RcsFeature. * Create a new RcsFeature.
@@ -255,26 +261,45 @@ public class RcsFeature extends ImsFeature {
* Method stubs called from the framework will be called asynchronously. To specify the * Method stubs called from the framework will be called asynchronously. To specify the
* {@link Executor} that the methods stubs will be called, use * {@link Executor} that the methods stubs will be called, use
* {@link RcsFeature#RcsFeature(Executor)} instead. * {@link RcsFeature#RcsFeature(Executor)} instead.
*
* @deprecated Use {@link #RcsFeature(Executor)} to create the RcsFeature.
*/ */
@Deprecated
public RcsFeature() { public RcsFeature() {
super(); super();
mExecutor = Runnable::run;
// Run on the Binder threads that call them. // Run on the Binder threads that call them.
mImsRcsBinder = new RcsFeatureBinder(this, Runnable::run); mImsRcsBinder = new RcsFeatureBinder(this, mExecutor);
} }
/** /**
* Create a new RcsFeature using the Executor specified for methods being called by the * Create a new RcsFeature using the Executor specified for methods being called by the
* framework. * framework.
* @param executor The executor for the framework to use when making calls to this service. * @param executor The executor for the framework to use when executing the methods overridden
* @hide * by the implementation of RcsFeature.
*/ */
public RcsFeature(@NonNull Executor executor) { public RcsFeature(@NonNull Executor executor) {
super(); super();
if (executor == null) { if (executor == null) {
throw new IllegalArgumentException("executor can not be null."); throw new IllegalArgumentException("executor can not be null.");
} }
mExecutor = executor;
// Run on the Binder thread by default. // Run on the Binder thread by default.
mImsRcsBinder = new RcsFeatureBinder(this, executor); mImsRcsBinder = new RcsFeatureBinder(this, mExecutor);
}
/**
* Called when the RcsFeature is initialized.
*
* @param context The context that is used in the ImsService.
* @param slotId The slot ID associated with the RcsFeature.
* @hide
*/
@Override
public void initialize(Context context, int slotId) {
super.initialize(context, slotId);
// Notify that the RcsFeature is ready.
mExecutor.execute(() -> onFeatureReady());
} }
/** /**
@@ -348,13 +373,26 @@ public class RcsFeature extends ImsFeature {
* operation and the RcsFeature sets the status of the capability to true using * operation and the RcsFeature sets the status of the capability to true using
* {@link #notifyCapabilitiesStatusChanged(RcsImsCapabilities)}. * {@link #notifyCapabilitiesStatusChanged(RcsImsCapabilities)}.
* *
* @return An instance of {@link RcsCapabilityExchangeImplBase} that implements presence * @param executor The executor for the framework to use when request RCS resquests to this
* service.
* @param listener A {@link CapabilityExchangeEventListener} to send the capability exchange
* event to the framework.
* @return An instance of {@link RcsCapabilityExchangeImplBase} that implements capability
* exchange if it is supported by the device. * exchange if it is supported by the device.
* @hide
*/ */
public @NonNull RcsCapabilityExchangeImplBase createCapabilityExchangeImpl() { public @NonNull RcsCapabilityExchangeImplBase createCapabilityExchangeImpl(
@NonNull Executor executor, @NonNull CapabilityExchangeEventListener listener) {
// Base Implementation, override to implement functionality // Base Implementation, override to implement functionality
return new RcsCapabilityExchangeImplBase(); return new RcsCapabilityExchangeImplBase(executor);
}
/**
* Remove the given CapabilityExchangeImplBase instance.
* @param capExchangeImpl The {@link RcsCapabilityExchangeImplBase} instance to be removed.
*/
public void removeCapabilityExchangeImpl(
@NonNull RcsCapabilityExchangeImplBase capExchangeImpl) {
// Override to implement the process of removing RcsCapabilityExchangeImplBase instance.
} }
/**{@inheritDoc}*/ /**{@inheritDoc}*/
@@ -377,18 +415,58 @@ public class RcsFeature extends ImsFeature {
return mImsRcsBinder; return mImsRcsBinder;
} }
private void setCapabilityExchangeEventListener(ICapabilityExchangeEventListener listener) { /**
mCapExchangeEventListener = listener; * Set the capability exchange listener.
if (mCapExchangeEventListener != null) { * @param executor The executor for the framework to use when request RCS requests to this
onFeatureReady(); * service.
* @param listener A {@link CapabilityExchangeEventListener} to send the capability exchange
* event to the framework.
*/
private void setCapabilityExchangeEventListener(@NonNull Executor executor,
@Nullable CapabilityExchangeEventListener listener) {
synchronized (mLock) {
mCapExchangeEventListener = listener;
if (mCapExchangeEventListener != null) {
initRcsCapabilityExchangeImplBase(executor, mCapExchangeEventListener);
} else {
// Remove the RcsCapabilityExchangeImplBase instance when the capability exchange
// instance has been removed in the framework.
if (mCapabilityExchangeImpl != null) {
removeCapabilityExchangeImpl(mCapabilityExchangeImpl);
}
mCapabilityExchangeImpl = null;
}
} }
} }
private RcsCapabilityExchangeImplBase getCapabilityExchangeImplBaseInternal() { /**
* Initialize the RcsCapabilityExchangeImplBase instance if the capability exchange instance
* has already been created in the framework.
* @param executor The executor for the framework to use when request RCS requests to this
* service.
* @param listener A {@link CapabilityExchangeEventListener} to send the capability exchange
* event to the framework.
*/
private void initRcsCapabilityExchangeImplBase(@NonNull Executor executor,
@NonNull CapabilityExchangeEventListener listener) {
synchronized (mLock) { synchronized (mLock) {
// Remove the original instance
if (mCapabilityExchangeImpl != null) {
removeCapabilityExchangeImpl(mCapabilityExchangeImpl);
}
mCapabilityExchangeImpl = createCapabilityExchangeImpl(executor, listener);
}
}
/**
* @return the {@link RcsCapabilityExchangeImplBase} associated with the RcsFeature.
*/
private @NonNull RcsCapabilityExchangeImplBase getCapabilityExchangeImplBaseInternal() {
synchronized (mLock) {
// The method should not be called if the instance of RcsCapabilityExchangeImplBase has
// not been created yet.
if (mCapabilityExchangeImpl == null) { if (mCapabilityExchangeImpl == null) {
mCapabilityExchangeImpl = createCapabilityExchangeImpl(); throw new IllegalStateException("Session is not available.");
mCapabilityExchangeImpl.setEventListener(mCapExchangeEventListener);
} }
return mCapabilityExchangeImpl; return mCapabilityExchangeImpl;
} }

View File

@@ -0,0 +1,108 @@
/*
* 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.stub;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.net.Uri;
import android.telephony.ims.ImsException;
import android.telephony.ims.RcsContactUceCapability;
import android.telephony.ims.RcsUceAdapter;
import android.telephony.ims.feature.ImsFeature;
import android.telephony.ims.feature.RcsFeature;
import java.util.List;
/**
* The interface of the capabilities event listener for ImsService to notify the framework of the
* UCE request and status updated.
* @hide
*/
@SystemApi
public interface CapabilityExchangeEventListener {
/**
* Interface used by the framework to respond to OPTIONS requests.
* @hide
*/
interface OptionsRequestCallback {
/**
* Respond to a remote capability request from the contact specified with the
* capabilities of this device.
* @param ownCapabilities The capabilities of this device.
*/
void onRespondToCapabilityRequest(@NonNull RcsContactUceCapability ownCapabilities);
/**
* Respond to a remote capability request from the contact specified with the
* specified error.
* @param code The SIP response code to respond with.
* @param reason A non-null String containing the reason associated with the SIP code.
*/
void onRespondToCapabilityRequestWithError(int code, @NonNull String reason);
}
/**
* Trigger the framework to provide a capability update using
* {@link RcsCapabilityExchangeImplBase#publishCapabilities}.
* <p>
* This is typically used when trying to generate an initial PUBLISH for a new subscription to
* the network. The device will cache all presence publications after boot until this method is
* called the first time.
* @param publishTriggerType {@link RcsUceAdapter#StackPublishTriggerType} The reason for the
* capability update request.
* @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is not currently
* connected to the framework. This can happen if the {@link RcsFeature} is not
* {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received the
* {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases when the
* Telephony stack has crashed.
*/
void onRequestPublishCapabilities(
@RcsUceAdapter.StackPublishTriggerType int publishTriggerType) throws ImsException;
/**
* Notify the framework that the device's capabilities have been unpublished
* from the network.
*
* @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is not currently
* connected to the framework. This can happen if the {@link RcsFeature} is not
* {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received the
* {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases when the
* Telephony stack has crashed.
*/
void onUnpublish() throws ImsException;
/**
* Inform the framework of a query for this device's UCE capabilities.
* <p>
* The framework will respond via the
* {@link OptionsRequestCallback#onRespondToCapabilityRequest} or
* {@link OptionsRequestCallback#onRespondToCapabilityRequestWithError}
* @param contactUri The URI associated with the remote contact that is
* requesting capabilities.
* @param remoteCapabilities The remote contact's capability information.
* @param callback The callback of this request which is sent from the remote user.
* @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is not
* currently connected to the framework. This can happen if the {@link RcsFeature} is not
* {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received
* the {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare
* cases when the Telephony stack has crashed.
* @hide
*/
void onRemoteCapabilityRequest(@NonNull Uri contactUri,
@NonNull List<String> remoteCapabilities,
@NonNull OptionsRequestCallback callback) throws ImsException;
}

View File

@@ -20,20 +20,28 @@ import android.annotation.IntDef;
import android.annotation.IntRange; import android.annotation.IntRange;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.net.Uri; import android.net.Uri;
import android.telephony.ims.ImsException; import android.telephony.ims.ImsException;
import android.telephony.ims.aidl.ICapabilityExchangeEventListener; import android.telephony.ims.feature.ImsFeature;
import android.telephony.ims.feature.RcsFeature;
import android.util.Log; import android.util.Log;
import android.util.Pair; import android.util.Pair;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.List; import java.util.List;
import java.util.concurrent.Executor;
/** /**
* Base class for different types of Capability exchange. * Extend this base class to implement RCS User Capability Exchange (UCE) for the AOSP platform
* using the vendor ImsService.
* <p>
* See RCC.07 for more details on UCE as well as how UCE should be implemented.
* @hide * @hide
*/ */
@SystemApi
public class RcsCapabilityExchangeImplBase { public class RcsCapabilityExchangeImplBase {
private static final String LOG_TAG = "RcsCapExchangeImplBase"; private static final String LOG_TAG = "RcsCapExchangeImplBase";
@@ -70,13 +78,11 @@ public class RcsCapabilityExchangeImplBase {
/** /**
* Network connection is lost. * Network connection is lost.
* @hide
*/ */
public static final int COMMAND_CODE_LOST_NETWORK_CONNECTION = 6; public static final int COMMAND_CODE_LOST_NETWORK_CONNECTION = 6;
/** /**
* Requested feature/resource is not supported. * Requested feature/resource is not supported.
* @hide
*/ */
public static final int COMMAND_CODE_NOT_SUPPORTED = 7; public static final int COMMAND_CODE_NOT_SUPPORTED = 7;
@@ -117,7 +123,8 @@ public class RcsCapabilityExchangeImplBase {
*/ */
public interface PublishResponseCallback { public interface PublishResponseCallback {
/** /**
* Notify the framework that the command associated with this callback has failed. * Notify the framework that the command associated with the
* {@link #publishCapabilities(String, PublishResponseCallback)} has failed.
* *
* @param code The reason why the associated command has failed. * @param code The reason why the associated command has failed.
* @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is
@@ -128,15 +135,15 @@ public class RcsCapabilityExchangeImplBase {
*/ */
void onCommandError(@CommandCode int code) throws ImsException; void onCommandError(@CommandCode int code) throws ImsException;
/** /**
* Provide the framework with a subsequent network response update to * Provide the framework with a subsequent network response update to
* {@link #publishCapabilities(String, PublishResponseCallback)}. * {@link #publishCapabilities(String, PublishResponseCallback)}.
* *
* @param code The SIP response code sent from the network for the operation * @param code The SIP response code sent from the network for the operation
* token specified. * token specified.
* @param reason The optional reason response from the network. If the network * @param reason The optional reason response from the network. If there is a reason header
* provided no reason with the code, the string should be empty. * included in the response, that should take precedence over the reason provided in the
* status line. If the network provided no reason with the code, the string should be empty.
* @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is
* not currently connected to the framework. This can happen if the {@link RcsFeature} * not currently connected to the framework. This can happen if the {@link RcsFeature}
* is not {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received * is not {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received
@@ -149,6 +156,7 @@ public class RcsCapabilityExchangeImplBase {
/** /**
* Interface used by the framework to respond to OPTIONS requests. * Interface used by the framework to respond to OPTIONS requests.
* @hide
*/ */
public interface OptionsResponseCallback { public interface OptionsResponseCallback {
/** /**
@@ -171,7 +179,7 @@ public class RcsCapabilityExchangeImplBase {
* If none was sent, this should be an empty string. * If none was sent, this should be an empty string.
* @param theirCaps the contact's UCE capabilities associated with the * @param theirCaps the contact's UCE capabilities associated with the
* capability request. * capability request.
* @throws ImsException If this {@link RcsSipOptionsImplBase} instance is not * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is not
* currently connected to the framework. This can happen if the * currently connected to the framework. This can happen if the
* {@link RcsFeature} is not {@link ImsFeature#STATE_READY} and the * {@link RcsFeature} is not {@link ImsFeature#STATE_READY} and the
* {@link RcsFeature} has not received the * {@link RcsFeature} has not received the
@@ -184,6 +192,7 @@ public class RcsCapabilityExchangeImplBase {
/** /**
* Interface used by the framework to receive the response of the subscribe request. * Interface used by the framework to receive the response of the subscribe request.
* @hide
*/ */
public interface SubscribeResponseCallback { public interface SubscribeResponseCallback {
/** /**
@@ -219,17 +228,16 @@ public class RcsCapabilityExchangeImplBase {
/** /**
* Provides the framework with latest XML PIDF documents included in the * Provides the framework with latest XML PIDF documents included in the
* network response for the requested contacts' capabilities requested by the * network response for the requested contacts' capabilities requested by the
* Framework using {@link #requestCapabilities(List, int)}. This should be * Framework using {@link #requestCapabilities(List, int)}. This should be
* called every time a new NOTIFY event is received with new capability * called every time a new NOTIFY event is received with new capability
* information. * information.
* *
* @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is
* not currently * not currently connected to the framework.
* connected to the framework. This can happen if the {@link RcsFeature} is not * This can happen if the {@link RcsFeature} is not {@link ImsFeature#STATE_READY} and the
* {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received * {@link RcsFeature} {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not
* the {@link ImsFeature#onFeatureReady()} callback. This may also happen in * received the {@link ImsFeature#onFeatureReady()} callback. This may also happen in
* rare cases when the * rare cases when the Telephony stack has crashed.
* Telephony stack has crashed.
*/ */
void onNotifyCapabilitiesUpdate(@NonNull List<String> pidfXmls) throws ImsException; void onNotifyCapabilitiesUpdate(@NonNull List<String> pidfXmls) throws ImsException;
@@ -250,24 +258,21 @@ public class RcsCapabilityExchangeImplBase {
* This allows the framework to know that there will no longer be any * This allows the framework to know that there will no longer be any
* capability updates for the requested operationToken. * capability updates for the requested operationToken.
*/ */
void onTerminated(String reason, long retryAfterMilliseconds) throws ImsException; void onTerminated(@NonNull String reason, long retryAfterMilliseconds) throws ImsException;
} }
private final Executor mBinderExecutor;
private ICapabilityExchangeEventListener mListener;
/** /**
* Set the event listener to send the request to Framework. * Create a new RcsCapabilityExchangeImplBase instance.
*
* @param executor The executor that remote calls from the framework will be called on.
*/ */
public void setEventListener(ICapabilityExchangeEventListener listener) { public RcsCapabilityExchangeImplBase(@NonNull Executor executor) {
mListener = listener; if (executor == null) {
} throw new IllegalArgumentException("executor must not be null");
}
/** mBinderExecutor = executor;
* Get the event listener.
*/
public ICapabilityExchangeEventListener getEventListener() {
return mListener;
} }
/** /**
@@ -284,7 +289,10 @@ public class RcsCapabilityExchangeImplBase {
* @param uris A {@link List} of the {@link Uri}s that the framework is requesting the UCE * @param uris A {@link List} of the {@link Uri}s that the framework is requesting the UCE
* capabilities for. * capabilities for.
* @param cb The callback of the subscribe request. * @param cb The callback of the subscribe request.
* @hide
*/ */
// executor used is defined in the constructor.
@SuppressLint("ExecutorRegistration")
public void subscribeForCapabilities(@NonNull List<Uri> uris, public void subscribeForCapabilities(@NonNull List<Uri> uris,
@NonNull SubscribeResponseCallback cb) { @NonNull SubscribeResponseCallback cb) {
// Stub - to be implemented by service // Stub - to be implemented by service
@@ -300,11 +308,13 @@ public class RcsCapabilityExchangeImplBase {
* The capabilities of this device have been updated and should be published to the network. * The capabilities of this device have been updated and should be published to the network.
* <p> * <p>
* If this operation succeeds, network response updates should be sent to the framework using * If this operation succeeds, network response updates should be sent to the framework using
* {@link #onNetworkResponse(int, String)}. * {@link PublishResponseCallback#onNetworkResponse(int, String)}.
* @param pidfXml The XML PIDF document containing the capabilities of this device to be sent * @param pidfXml The XML PIDF document containing the capabilities of this device to be sent
* to the carriers presence server. * to the carriers presence server.
* @param cb The callback of the publish request * @param cb The callback of the publish request
*/ */
// executor used is defined in the constructor.
@SuppressLint("ExecutorRegistration")
public void publishCapabilities(@NonNull String pidfXml, @NonNull PublishResponseCallback cb) { public void publishCapabilities(@NonNull String pidfXml, @NonNull PublishResponseCallback cb) {
// Stub - to be implemented by service // Stub - to be implemented by service
Log.w(LOG_TAG, "publishCapabilities called with no implementation."); Log.w(LOG_TAG, "publishCapabilities called with no implementation.");
@@ -324,7 +334,10 @@ public class RcsCapabilityExchangeImplBase {
* @param contactUri The URI of the remote user that we wish to get the capabilities of. * @param contactUri The URI of the remote user that we wish to get the capabilities of.
* @param myCapabilities The capabilities of this device to send to the remote user. * @param myCapabilities The capabilities of this device to send to the remote user.
* @param callback The callback of this request which is sent from the remote user. * @param callback The callback of this request which is sent from the remote user.
* @hide
*/ */
// executor used is defined in the constructor.
@SuppressLint("ExecutorRegistration")
public void sendOptionsCapabilityRequest(@NonNull Uri contactUri, public void sendOptionsCapabilityRequest(@NonNull Uri contactUri,
@NonNull List<String> myCapabilities, @NonNull OptionsResponseCallback callback) { @NonNull List<String> myCapabilities, @NonNull OptionsResponseCallback callback) {
// Stub - to be implemented by service // Stub - to be implemented by service