Merge "Update the RCS UCE APIs."
This commit is contained in:
@@ -11567,7 +11567,7 @@ package android.telephony.ims {
|
||||
method @NonNull public String getServiceId();
|
||||
method @NonNull public String getServiceVersion();
|
||||
method @NonNull public String getStatus();
|
||||
method @Nullable public String getTimestamp();
|
||||
method @Nullable public java.time.Instant getTime();
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.RcsContactPresenceTuple> CREATOR;
|
||||
field public static final String SERVICE_ID_CALL_COMPOSER = "org.3gpp.urn:urn-7:3gpp-service.ims.icsi.gsma.callcomposer";
|
||||
@@ -11594,7 +11594,7 @@ package android.telephony.ims {
|
||||
method @NonNull public android.telephony.ims.RcsContactPresenceTuple.Builder setContactUri(@NonNull android.net.Uri);
|
||||
method @NonNull public android.telephony.ims.RcsContactPresenceTuple.Builder setServiceCapabilities(@NonNull android.telephony.ims.RcsContactPresenceTuple.ServiceCapabilities);
|
||||
method @NonNull public android.telephony.ims.RcsContactPresenceTuple.Builder setServiceDescription(@NonNull String);
|
||||
method @NonNull public android.telephony.ims.RcsContactPresenceTuple.Builder setTimestamp(@NonNull String);
|
||||
method @NonNull public android.telephony.ims.RcsContactPresenceTuple.Builder setTime(@NonNull java.time.Instant);
|
||||
}
|
||||
|
||||
public static final class RcsContactPresenceTuple.ServiceCapabilities implements android.os.Parcelable {
|
||||
@@ -11650,7 +11650,7 @@ package android.telephony.ims {
|
||||
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(allOf={android.Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE, android.Manifest.permission.READ_CONTACTS}) public void requestAvailability(@NonNull android.net.Uri, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RcsUceAdapter.CapabilitiesCallback) throws android.telephony.ims.ImsException;
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE, android.Manifest.permission.READ_CONTACTS}) public void requestCapabilities(@NonNull java.util.List<android.net.Uri>, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RcsUceAdapter.CapabilitiesCallback) throws android.telephony.ims.ImsException;
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE, android.Manifest.permission.READ_CONTACTS}) public void requestCapabilities(@NonNull java.util.Collection<android.net.Uri>, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RcsUceAdapter.CapabilitiesCallback) 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_TYPE_PRESENCE_UCE = 2; // 0x2
|
||||
field public static final int CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED = 1; // 0x1
|
||||
@@ -12127,7 +12127,7 @@ package android.telephony.ims.stub {
|
||||
ctor public RcsCapabilityExchangeImplBase(@NonNull java.util.concurrent.Executor);
|
||||
method public void publishCapabilities(@NonNull String, @NonNull android.telephony.ims.stub.RcsCapabilityExchangeImplBase.PublishResponseCallback);
|
||||
method public void sendOptionsCapabilityRequest(@NonNull android.net.Uri, @NonNull java.util.List<java.lang.String>, @NonNull android.telephony.ims.stub.RcsCapabilityExchangeImplBase.OptionsResponseCallback);
|
||||
method public void subscribeForCapabilities(@NonNull java.util.List<android.net.Uri>, @NonNull android.telephony.ims.stub.RcsCapabilityExchangeImplBase.SubscribeResponseCallback);
|
||||
method public void subscribeForCapabilities(@NonNull java.util.Collection<android.net.Uri>, @NonNull android.telephony.ims.stub.RcsCapabilityExchangeImplBase.SubscribeResponseCallback);
|
||||
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
|
||||
|
||||
@@ -23,9 +23,14 @@ import android.annotation.SystemApi;
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.time.Instant;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -38,6 +43,8 @@ import java.util.List;
|
||||
@SystemApi
|
||||
public final class RcsContactPresenceTuple implements Parcelable {
|
||||
|
||||
private static final String LOG_TAG = "RcsContactPresenceTuple";
|
||||
|
||||
/**
|
||||
* The service ID used to indicate that MMTEL service is available.
|
||||
* <p>
|
||||
@@ -353,7 +360,8 @@ public final 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 if the network
|
||||
* expects the user to use the URI instead of the contact URI to contact it.
|
||||
*/
|
||||
public @NonNull Builder setContactUri(@NonNull Uri contactUri) {
|
||||
mPresenceTuple.mContactUri = contactUri;
|
||||
@@ -364,8 +372,24 @@ public final class RcsContactPresenceTuple implements Parcelable {
|
||||
* The optional timestamp indicating the data and time of the status change of this tuple.
|
||||
* Per RFC3863 section 4.1.7, the timestamp is formatted as an IMPP datetime format
|
||||
* string per RFC3339.
|
||||
* @hide
|
||||
*/
|
||||
public @NonNull Builder setTimestamp(@NonNull String timestamp) {
|
||||
try {
|
||||
mPresenceTuple.mTimestamp =
|
||||
DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(timestamp, Instant::from);
|
||||
} catch (DateTimeParseException e) {
|
||||
Log.d(LOG_TAG, "Parse timestamp failed " + e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The optional timestamp indicating the data and time of the status change of this tuple.
|
||||
* Per RFC3863 section 4.1.7, the timestamp is formatted as an IMPP datetime format
|
||||
* string per RFC3339.
|
||||
*/
|
||||
public @NonNull Builder setTime(@NonNull Instant timestamp) {
|
||||
mPresenceTuple.mTimestamp = timestamp;
|
||||
return this;
|
||||
}
|
||||
@@ -397,7 +421,7 @@ public final class RcsContactPresenceTuple implements Parcelable {
|
||||
}
|
||||
|
||||
private Uri mContactUri;
|
||||
private String mTimestamp;
|
||||
private Instant mTimestamp;
|
||||
private @BasicStatus String mStatus;
|
||||
|
||||
// The service information in the service-description element.
|
||||
@@ -416,7 +440,7 @@ public final class RcsContactPresenceTuple implements Parcelable {
|
||||
|
||||
private RcsContactPresenceTuple(Parcel in) {
|
||||
mContactUri = in.readParcelable(Uri.class.getClassLoader());
|
||||
mTimestamp = in.readString();
|
||||
mTimestamp = convertStringFormatTimeToInstant(in.readString());
|
||||
mStatus = in.readString();
|
||||
mServiceId = in.readString();
|
||||
mServiceVersion = in.readString();
|
||||
@@ -427,7 +451,7 @@ public final class RcsContactPresenceTuple implements Parcelable {
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel out, int flags) {
|
||||
out.writeParcelable(mContactUri, flags);
|
||||
out.writeString(mTimestamp);
|
||||
out.writeString(convertInstantToStringFormat(mTimestamp));
|
||||
out.writeString(mStatus);
|
||||
out.writeString(mServiceId);
|
||||
out.writeString(mServiceVersion);
|
||||
@@ -453,6 +477,26 @@ public final class RcsContactPresenceTuple implements Parcelable {
|
||||
}
|
||||
};
|
||||
|
||||
// Convert the Instant to the string format
|
||||
private String convertInstantToStringFormat(Instant instant) {
|
||||
if (instant == null) {
|
||||
return "";
|
||||
}
|
||||
return instant.toString();
|
||||
}
|
||||
|
||||
// Convert the time string format to Instant
|
||||
private @Nullable Instant convertStringFormatTimeToInstant(String timestamp) {
|
||||
if (TextUtils.isEmpty(timestamp)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(timestamp, Instant::from);
|
||||
} catch (DateTimeParseException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** @return the status of the tuple element. */
|
||||
public @NonNull @BasicStatus String getStatus() {
|
||||
return mStatus;
|
||||
@@ -473,8 +517,16 @@ public final class RcsContactPresenceTuple implements Parcelable {
|
||||
return mContactUri;
|
||||
}
|
||||
|
||||
/** @return the timestamp element contained in the tuple if it exists */
|
||||
/**
|
||||
* @return the timestamp element contained in the tuple if it exists
|
||||
* @hide
|
||||
*/
|
||||
public @Nullable String getTimestamp() {
|
||||
return (mTimestamp == null) ? null : mTimestamp.toString();
|
||||
}
|
||||
|
||||
/** @return the timestamp element contained in the tuple if it exists */
|
||||
public @Nullable Instant getTime() {
|
||||
return mTimestamp;
|
||||
}
|
||||
|
||||
|
||||
@@ -339,6 +339,7 @@ public final class RcsContactUceCapability implements Parcelable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the contact URI requested by the applications.
|
||||
* @return the URI representing the contact associated with the capabilities.
|
||||
*/
|
||||
public @NonNull Uri getContactUri() {
|
||||
|
||||
@@ -36,6 +36,8 @@ import android.util.Log;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -430,13 +432,15 @@ public class RcsUceAdapter {
|
||||
|
||||
/**
|
||||
* The pending request has completed successfully due to all requested contacts information
|
||||
* being delivered.
|
||||
* being delivered. The callback {@link #onCapabilitiesReceived(List)}
|
||||
* for each contacts is required to be called before {@link #onComplete} is called.
|
||||
*/
|
||||
void onComplete();
|
||||
|
||||
/**
|
||||
* The pending request has resulted in an error and may need to be retried, depending on the
|
||||
* error code.
|
||||
* error code. The callback {@link #onCapabilitiesReceived(List)}
|
||||
* for each contacts is required to be called before {@link #onError} is called.
|
||||
* @param errorCode The reason for the framework being unable to process the request.
|
||||
* @param retryIntervalMillis The time in milliseconds the requesting application should
|
||||
* wait before retrying, if non-zero.
|
||||
@@ -483,7 +487,6 @@ public class RcsUceAdapter {
|
||||
* becomes inactive. See {@link ImsException#getCode()} for more information on the error codes.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(allOf = {Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE,
|
||||
Manifest.permission.READ_CONTACTS})
|
||||
public void requestCapabilities(@NonNull List<Uri> contactNumbers,
|
||||
@@ -548,6 +551,94 @@ public class RcsUceAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the User Capability Exchange capabilities for one or more contacts.
|
||||
* <p>
|
||||
* This will return the cached capabilities of the contact and will not perform a capability
|
||||
* poll on the network unless there are contacts being queried with stale information.
|
||||
* <p>
|
||||
* Be sure to check the availability of this feature using
|
||||
* {@link ImsRcsManager#isAvailable(int, int)} and ensuring
|
||||
* {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_OPTIONS_UCE} or
|
||||
* {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_PRESENCE_UCE} is enabled or else
|
||||
* this operation will fail with {@link #ERROR_NOT_AVAILABLE} or {@link #ERROR_NOT_ENABLED}.
|
||||
*
|
||||
* @param contactNumbers A list of numbers that the capabilities are being requested for.
|
||||
* @param executor The executor that will be used when the request is completed and the
|
||||
* {@link CapabilitiesCallback} is called.
|
||||
* @param c A one-time callback for when the request for capabilities completes or there is an
|
||||
* error processing the request.
|
||||
* @throws ImsException if the subscription associated with this instance of
|
||||
* {@link RcsUceAdapter} is valid, but the ImsService associated with the subscription is not
|
||||
* available. This can happen if the ImsService has crashed, for example, or if the subscription
|
||||
* becomes inactive. See {@link ImsException#getCode()} for more information on the error codes.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(allOf = {Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE,
|
||||
Manifest.permission.READ_CONTACTS})
|
||||
public void requestCapabilities(@NonNull Collection<Uri> contactNumbers,
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull CapabilitiesCallback c) throws ImsException {
|
||||
if (c == null) {
|
||||
throw new IllegalArgumentException("Must include a non-null CapabilitiesCallback.");
|
||||
}
|
||||
if (executor == null) {
|
||||
throw new IllegalArgumentException("Must include a non-null Executor.");
|
||||
}
|
||||
if (contactNumbers == null) {
|
||||
throw new IllegalArgumentException("Must include non-null contact number list.");
|
||||
}
|
||||
|
||||
IImsRcsController imsRcsController = getIImsRcsController();
|
||||
if (imsRcsController == null) {
|
||||
Log.e(TAG, "requestCapabilities: IImsRcsController is null");
|
||||
throw new ImsException("Can not find remote IMS service",
|
||||
ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
|
||||
IRcsUceControllerCallback internalCallback = new IRcsUceControllerCallback.Stub() {
|
||||
@Override
|
||||
public void onCapabilitiesReceived(List<RcsContactUceCapability> contactCapabilities) {
|
||||
final long callingIdentity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
executor.execute(() -> c.onCapabilitiesReceived(contactCapabilities));
|
||||
} finally {
|
||||
restoreCallingIdentity(callingIdentity);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onComplete() {
|
||||
final long callingIdentity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
executor.execute(() -> c.onComplete());
|
||||
} finally {
|
||||
restoreCallingIdentity(callingIdentity);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onError(int errorCode, long retryAfterMilliseconds) {
|
||||
final long callingIdentity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
executor.execute(() -> c.onError(errorCode, retryAfterMilliseconds));
|
||||
} finally {
|
||||
restoreCallingIdentity(callingIdentity);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
imsRcsController.requestCapabilities(mSubId, mContext.getOpPackageName(),
|
||||
mContext.getAttributionTag(), new ArrayList(contactNumbers), internalCallback);
|
||||
} catch (ServiceSpecificException e) {
|
||||
throw new ImsException(e.toString(), e.errorCode);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error calling IImsRcsController#requestCapabilities", e);
|
||||
throw new ImsException("Remote IMS Service is not available",
|
||||
ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ignore the device cache and perform a capability discovery for one contact, also called
|
||||
* "availability fetch."
|
||||
@@ -569,6 +660,10 @@ public class RcsUceAdapter {
|
||||
* {@link CapabilitiesCallback} is called.
|
||||
* @param c A one-time callback for when the request for capabilities completes or there is
|
||||
* an error processing the request.
|
||||
* @throws ImsException if the subscription associated with this instance of
|
||||
* {@link RcsUceAdapter} is valid, but the ImsService associated with the subscription is not
|
||||
* available. This can happen if the ImsService has crashed, for example, or if the subscription
|
||||
* becomes inactive. See {@link ImsException#getCode()} for more information on the error codes.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
|
||||
@@ -31,6 +31,7 @@ import android.util.Pair;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@@ -241,7 +242,7 @@ public class RcsCapabilityExchangeImplBase {
|
||||
|
||||
/**
|
||||
* Notify the framework of the response to the SUBSCRIBE request from
|
||||
* {@link #subscribeForCapabilities(List, SubscribeResponseCallback)}.
|
||||
* {@link #subscribeForCapabilities(Collection, SubscribeResponseCallback)}.
|
||||
* <p>
|
||||
* If the carrier network responds to the SUBSCRIBE request with a 2XX response, then the
|
||||
* framework will expect the IMS stack to call {@link #onNotifyCapabilitiesUpdate},
|
||||
@@ -266,7 +267,7 @@ public class RcsCapabilityExchangeImplBase {
|
||||
|
||||
/**
|
||||
* Notify the framework of the response to the SUBSCRIBE request from
|
||||
* {@link #subscribeForCapabilities(List, SubscribeResponseCallback)} that also
|
||||
* {@link #subscribeForCapabilities(Collection, SubscribeResponseCallback)} that also
|
||||
* includes a reason provided in the “reason” header. See RFC3326 for more
|
||||
* information.
|
||||
*
|
||||
@@ -388,6 +389,7 @@ public class RcsCapabilityExchangeImplBase {
|
||||
* @param uris A {@link List} of the {@link Uri}s that the framework is requesting the UCE
|
||||
* capabilities for.
|
||||
* @param cb The callback of the subscribe request.
|
||||
* @hide
|
||||
*/
|
||||
// executor used is defined in the constructor.
|
||||
@SuppressLint("ExecutorRegistration")
|
||||
@@ -402,6 +404,40 @@ public class RcsCapabilityExchangeImplBase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The user capabilities of one or multiple contacts have been requested by the framework.
|
||||
* <p>
|
||||
* The implementer must follow up this call with an
|
||||
* {@link SubscribeResponseCallback#onCommandError} call to indicate this operation has failed.
|
||||
* The response from the network to the SUBSCRIBE request must be sent back to the framework
|
||||
* using {@link SubscribeResponseCallback#onNetworkResponse(int, String)}.
|
||||
* As NOTIFY requests come in from the network, the requested contact’s capabilities should be
|
||||
* sent back to the framework using
|
||||
* {@link SubscribeResponseCallback#onNotifyCapabilitiesUpdate(List<String>}) and
|
||||
* {@link SubscribeResponseCallback#onResourceTerminated(List<Pair<Uri, String>>)}
|
||||
* should be called with the presence information for the contacts specified.
|
||||
* <p>
|
||||
* Once the subscription is terminated,
|
||||
* {@link SubscribeResponseCallback#onTerminated(String, long)} must be called for the
|
||||
* framework to finish listening for NOTIFY responses.
|
||||
*
|
||||
* @param uris A {@link Collection} of the {@link Uri}s that the framework is requesting the
|
||||
* UCE capabilities for.
|
||||
* @param cb The callback of the subscribe request.
|
||||
*/
|
||||
// executor used is defined in the constructor.
|
||||
@SuppressLint("ExecutorRegistration")
|
||||
public void subscribeForCapabilities(@NonNull Collection<Uri> uris,
|
||||
@NonNull SubscribeResponseCallback cb) {
|
||||
// Stub - to be implemented by service
|
||||
Log.w(LOG_TAG, "subscribeForCapabilities called with no implementation.");
|
||||
try {
|
||||
cb.onCommandError(COMMAND_CODE_NOT_SUPPORTED);
|
||||
} catch (ImsException e) {
|
||||
// Do not do anything, this is a stub implementation.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The capabilities of this device have been updated and should be published to the network.
|
||||
* <p>
|
||||
|
||||
Reference in New Issue
Block a user