diff options
Diffstat (limited to 'telephony')
13 files changed, 316 insertions, 124 deletions
diff --git a/telephony/java/android/telephony/CarrierBandwidth.java b/telephony/java/android/telephony/CarrierBandwidth.java index b153fefce6e3..9e1dee0162b9 100644 --- a/telephony/java/android/telephony/CarrierBandwidth.java +++ b/telephony/java/android/telephony/CarrierBandwidth.java @@ -101,7 +101,7 @@ public final class CarrierBandwidth implements Parcelable { } /** - * Retrieves the upstream bandwidth for the primary network in Kbps. This always only refers to + * Retrieves the upstream bandwidth for the primary network in kbps. This always only refers to * the estimated first hop transport bandwidth. * This will be {@link #INVALID} if the network is not connected * @@ -112,7 +112,7 @@ public final class CarrierBandwidth implements Parcelable { } /** - * Retrieves the downstream bandwidth for the primary network in Kbps. This always only refers + * Retrieves the downstream bandwidth for the primary network in kbps. This always only refers * to the estimated first hop transport bandwidth. * This will be {@link #INVALID} if the network is not connected * @@ -123,7 +123,7 @@ public final class CarrierBandwidth implements Parcelable { } /** - * Retrieves the upstream bandwidth for the secondary network in Kbps. This always only refers + * Retrieves the upstream bandwidth for the secondary network in kbps. This always only refers * to the estimated first hop transport bandwidth. * <p/> * This will be {@link #INVALID} if either are the case: @@ -143,7 +143,7 @@ public final class CarrierBandwidth implements Parcelable { } /** - * Retrieves the downstream bandwidth for the secondary network in Kbps. This always only + * Retrieves the downstream bandwidth for the secondary network in kbps. This always only * refers to the estimated first hop transport bandwidth. * <p/> * This will be {@link #INVALID} if either are the case: diff --git a/telephony/java/android/telephony/CellIdentity.java b/telephony/java/android/telephony/CellIdentity.java index 1e5ce05ff28a..518fabc09838 100644 --- a/telephony/java/android/telephony/CellIdentity.java +++ b/telephony/java/android/telephony/CellIdentity.java @@ -37,7 +37,7 @@ import java.util.UUID; public abstract class CellIdentity implements Parcelable { /** @hide */ - public static final int INVALID_CHANNEL_NUMBER = -1; + public static final int INVALID_CHANNEL_NUMBER = Integer.MAX_VALUE; /** * parameters for validation diff --git a/telephony/java/android/telephony/PhysicalChannelConfig.java b/telephony/java/android/telephony/PhysicalChannelConfig.java index 9fb098ea8758..dfe269cbb0d9 100644 --- a/telephony/java/android/telephony/PhysicalChannelConfig.java +++ b/telephony/java/android/telephony/PhysicalChannelConfig.java @@ -50,7 +50,7 @@ public final class PhysicalChannelConfig implements Parcelable { public static final int CONNECTION_UNKNOWN = -1; /** Channel number is unknown. */ - public static final int CHANNEL_NUMBER_UNKNOWN = -1; + public static final int CHANNEL_NUMBER_UNKNOWN = Integer.MAX_VALUE; /** Physical Cell Id is unknown. */ public static final int PHYSICAL_CELL_ID_UNKNOWN = -1; diff --git a/telephony/java/android/telephony/TelephonyDisplayInfo.java b/telephony/java/android/telephony/TelephonyDisplayInfo.java index 1fcb504e7895..877827578760 100644 --- a/telephony/java/android/telephony/TelephonyDisplayInfo.java +++ b/telephony/java/android/telephony/TelephonyDisplayInfo.java @@ -30,8 +30,8 @@ import java.util.Objects; * necessarily a precise or accurate representation of the current state and should be treated * accordingly. * To be notified of changes in TelephonyDisplayInfo, use - * {@link TelephonyManager#registerPhoneStateListener} with a {@link PhoneStateListener} - * that implements {@link PhoneStateListener.DisplayInfoChangedListener}. + * {@link TelephonyManager#registerTelephonyCallback} with a {@link TelephonyCallback} + * that implements {@link TelephonyCallback.DisplayInfoListener}. * Override the onDisplayInfoChanged() method to handle the broadcast. */ public final class TelephonyDisplayInfo implements Parcelable { diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index f12ff93ecb36..23dcee6387b8 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -5580,28 +5580,25 @@ public class TelephonyManager { * instability. If a process has registered too many listeners without unregistering them, it * may encounter an {@link IllegalStateException} when trying to register more listeners. * - * @param listener The {@link PhoneStateListener} object to register (or unregister) - * @param events The telephony state(s) of interest to the listener, as a bitwise-OR combination - * of {@link PhoneStateListener} LISTEN_ flags. - * @deprecated Use {@link #registerPhoneStateListener(Executor, PhoneStateListener)}. + * @param listener The {@link PhoneStateListener} object to register + * (or unregister) + * @param events The telephony state(s) of interest to the listener, + * as a bitwise-OR combination of {@link PhoneStateListener} + * LISTEN_ flags. + * @deprecated Use {@link #registerTelephonyCallback(Executor, TelephonyCallback)}. */ @Deprecated public void listen(PhoneStateListener listener, int events) { - if (!listener.isExecutorSet()) { - throw new IllegalStateException("PhoneStateListener should be created on a thread " - + "with Looper.myLooper() != null"); - } - boolean notifyNow = getITelephony() != null; - mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class); - if (mTelephonyRegistryMgr != null) { - if (events != PhoneStateListener.LISTEN_NONE) { - mTelephonyRegistryMgr.registerPhoneStateListenerWithEvents(mSubId, - getOpPackageName(), getAttributionTag(), listener, events, notifyNow); - } else { - unregisterPhoneStateListener(listener); - } + if (mContext == null) return; + boolean notifyNow = (getITelephony() != null); + TelephonyRegistryManager telephonyRegistry = + (TelephonyRegistryManager) + mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); + if (telephonyRegistry != null) { + telephonyRegistry.listenFromListener(mSubId, getOpPackageName(), + getAttributionTag(), listener, events, notifyNow); } else { - throw new IllegalStateException("telephony service is null."); + Rlog.w(TAG, "telephony registry not ready."); } } @@ -14123,12 +14120,11 @@ public class TelephonyManager { * {@link #NR_DUAL_CONNECTIVITY_DISABLE_IMMEDIATE} * </ol> * @return operation result. - * <p>Requires Permission: - * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} * @throws IllegalStateException if the Telephony process is not currently available. * @hide */ @SystemApi + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public @EnableNrDualConnectivityResult int setNrDualConnectivityState( @NrDualConnectivityState int nrDualConnectivityState) { try { @@ -14548,6 +14544,75 @@ public class TelephonyManager { return THERMAL_MITIGATION_RESULT_UNKNOWN_ERROR; } + /** + * Registers a callback object to receive notification of changes in specified telephony states. + * <p> + * To register a callback, pass a {@link TelephonyCallback} which implements + * interfaces of events. For example, + * FakeServiceStateCallback extends {@link TelephonyCallback} implements + * {@link TelephonyCallback.ServiceStateListener}. + * + * At registration, and when a specified telephony state changes, the telephony manager invokes + * the appropriate callback method on the callback object and passes the current (updated) + * values. + * <p> + * + * If this TelephonyManager object has been created with {@link #createForSubscriptionId}, + * applies to the given subId. Otherwise, applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. To register events for multiple + * subIds, pass a separate callback object to each TelephonyManager object created with + * {@link #createForSubscriptionId}. + * + * Note: if you call this method while in the middle of a binder transaction, you <b>must</b> + * call {@link android.os.Binder#clearCallingIdentity()} before calling this method. A + * {@link SecurityException} will be thrown otherwise. + * + * This API should be used sparingly -- large numbers of callbacks will cause system + * instability. If a process has registered too many callbacks without unregistering them, it + * may encounter an {@link IllegalStateException} when trying to register more callbacks. + * + * @param executor The executor of where the callback will execute. + * @param callback The {@link TelephonyCallback} object to register. + */ + public void registerTelephonyCallback(@NonNull @CallbackExecutor Executor executor, + @NonNull TelephonyCallback callback) { + if (executor == null || callback == null) { + throw new IllegalArgumentException("TelephonyCallback and executor must be non-null"); + } + mTelephonyRegistryMgr = (TelephonyRegistryManager) + mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); + if (mTelephonyRegistryMgr != null) { + mTelephonyRegistryMgr.registerTelephonyCallback(executor, mSubId, getOpPackageName(), + getAttributionTag(), callback, getITelephony() != null); + } else { + throw new IllegalStateException("telephony service is null."); + } + } + + /** + * Unregister an existing {@link TelephonyCallback}. + * + * @param callback The {@link TelephonyCallback} object to unregister. + */ + public void unregisterTelephonyCallback(@NonNull TelephonyCallback callback) { + + if (mContext == null) { + throw new IllegalStateException("telephony service is null."); + } + + if (callback.callback == null) { + return; + } + + mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class); + if (mTelephonyRegistryMgr != null) { + mTelephonyRegistryMgr.unregisterTelephonyCallback(mSubId, getOpPackageName(), + getAttributionTag(), callback, getITelephony() != null); + } else { + throw new IllegalStateException("telephony service is null."); + } + } + /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = {"GBA_FAILURE_REASON_"}, value = { @@ -14724,73 +14789,6 @@ public class TelephonyManager { } /** - * Registers a listener object to receive notification of changes in specified telephony states. - * <p> - * To register a listener, pass a {@link PhoneStateListener} which implements - * interfaces of events. For example, - * FakeServiceStateChangedListener extends {@link PhoneStateListener} implements - * {@link PhoneStateListener.ServiceStateChangedListener}. - * - * At registration, and when a specified telephony state changes, the telephony manager invokes - * the appropriate callback method on the listener object and passes the current (updated) - * values. - * <p> - * - * If this TelephonyManager object has been created with {@link #createForSubscriptionId}, - * applies to the given subId. Otherwise, applies to - * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID}. To listen events for multiple subIds, - * pass a separate listener object to each TelephonyManager object created with - * {@link #createForSubscriptionId}. Only {@link PhoneStateListener.CallStateChangedListener} - * can be used to receive changes for all subIds through - * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID}. - * - * Note: if you call this method while in the middle of a binder transaction, you <b>must</b> - * call {@link android.os.Binder#clearCallingIdentity()} before calling this method. A - * {@link SecurityException} will be thrown otherwise. - * - * This API should be used sparingly -- large numbers of listeners will cause system - * instability. If a process has registered too many listeners without unregistering them, it - * may encounter an {@link IllegalStateException} when trying to register more listeners. - * - * @param executor The executor of where the callback will execute. - * @param listener The {@link PhoneStateListener} object to register. - */ - public void registerPhoneStateListener(@NonNull @CallbackExecutor Executor executor, - @NonNull PhoneStateListener listener) { - if (executor == null || listener == null) { - throw new IllegalArgumentException("PhoneStateListener and executor must be non-null"); - } - mTelephonyRegistryMgr = (TelephonyRegistryManager) - mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); - if (mTelephonyRegistryMgr != null) { - mTelephonyRegistryMgr.registerPhoneStateListener(executor, mSubId, - getOpPackageName(), getAttributionTag(), listener, getITelephony() != null); - } else { - throw new IllegalStateException("telephony service is null."); - } - } - - /** - * Unregister an existing {@link PhoneStateListener}. - * - * @param listener The {@link PhoneStateListener} object to unregister. - */ - public void unregisterPhoneStateListener(@NonNull PhoneStateListener listener) { - - if (mContext == null) { - throw new IllegalStateException("telephony service is null."); - } - - mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class); - if (mTelephonyRegistryMgr != null) { - mTelephonyRegistryMgr.unregisterPhoneStateListener(mSubId, getOpPackageName(), - getAttributionTag(), listener, getITelephony() != null); - } else { - throw new IllegalStateException("telephony service is null."); - } - } - - /** * The network type is valid or not. * * @param networkType The network type {@link NetworkType}. diff --git a/telephony/java/android/telephony/data/DataServiceCallback.java b/telephony/java/android/telephony/data/DataServiceCallback.java index ca1f861f9808..363e47a6d242 100644 --- a/telephony/java/android/telephony/data/DataServiceCallback.java +++ b/telephony/java/android/telephony/data/DataServiceCallback.java @@ -254,15 +254,15 @@ public class DataServiceCallback { } /** - * The APN is throttled for the duration specified in - * {@link DataCallResponse#getRetryDurationMillis}. Calling this method unthrottles that - * APN. + * Unthrottles the APN on the current transport. There is no matching "APN throttle" method. + * Instead, the APN is throttled for the time specified in + * {@link DataCallResponse#getRetryDurationMillis}. * <p/> * see: {@link DataCallResponse#getRetryDurationMillis} * * @param apn Access Point Name defined by the carrier. */ - public void onApnUnthrottled(@NonNull String apn) { + public void onApnUnthrottled(final @NonNull String apn) { if (mCallback != null) { try { if (DBG) Rlog.d(TAG, "onApnUnthrottled"); diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java index a9ccb6aa64f2..aa9145b01be9 100644 --- a/telephony/java/android/telephony/ims/ProvisioningManager.java +++ b/telephony/java/android/telephony/ims/ProvisioningManager.java @@ -1006,7 +1006,8 @@ public class ProvisioningManager { * server) or other operator defined triggers. If RCS provisioning is already * completed at the time of callback registration, then this method shall be * invoked with the current configuration - * @param configXml The RCS configurationXML received OTA. + * @param configXml The RCS configuration XML received by OTA. It is defined + * by GSMA RCC.07. */ public void onConfigurationChanged(@NonNull byte[] configXml) {} @@ -1373,7 +1374,9 @@ public class ProvisioningManager { * provisioning is done using autoconfiguration, then these parameters shall be * sent in the HTTP get request to fetch the RCS provisioning. RCS client * configuration must be provided by the application before registering for the - * provisioning status events {@link #registerRcsProvisioningChangedCallback} + * provisioning status events {@link #registerRcsProvisioningCallback()} + * When the IMS/RCS service receives the RCS client configuration, it will detect + * the change in the configuration, and trigger the auto-configuration as needed. * @param rcc RCS client configuration {@link RcsClientConfiguration} */ @RequiresPermission(Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION) @@ -1440,7 +1443,7 @@ public class ProvisioningManager { * * @param executor The {@link Executor} to call the callback methods on * @param callback The rcs provisioning callback to be registered. - * @see #unregisterRcsProvisioningChangedCallback(RcsProvisioningCallback) + * @see #unregisterRcsProvisioningCallback(RcsProvisioningCallback) * @see SubscriptionManager.OnSubscriptionsChangedListener * @throws IllegalArgumentException if the subscription associated with this * callback is not active (SIM is not inserted, ESIM inactive) or the @@ -1456,12 +1459,12 @@ public class ProvisioningManager { */ @RequiresPermission(anyOf = {Manifest.permission.READ_PRIVILEGED_PHONE_STATE, Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION}) - public void registerRcsProvisioningChangedCallback( + public void registerRcsProvisioningCallback( @NonNull @CallbackExecutor Executor executor, @NonNull RcsProvisioningCallback callback) throws ImsException { callback.setExecutor(executor); try { - getITelephony().registerRcsProvisioningChangedCallback(mSubId, callback.getBinder()); + getITelephony().registerRcsProvisioningCallback(mSubId, callback.getBinder()); } catch (ServiceSpecificException e) { throw new ImsException(e.getMessage(), e.errorCode); } catch (RemoteException | IllegalStateException e) { @@ -1487,16 +1490,16 @@ public class ProvisioningManager { * * @param callback The existing {@link RcsProvisioningCallback} to be * removed. - * @see #registerRcsProvisioningChangedCallback - * @throws IllegalArgumentException if the subscription associated with this callback is - * invalid. + * @see #registerRcsProvisioningCallback(Executor, RcsProvisioningCallback) + * @throws IllegalArgumentException if the subscription associated with + * this callback is invalid. */ @RequiresPermission(anyOf = {Manifest.permission.READ_PRIVILEGED_PHONE_STATE, Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION}) - public void unregisterRcsProvisioningChangedCallback( + public void unregisterRcsProvisioningCallback( @NonNull RcsProvisioningCallback callback) { try { - getITelephony().unregisterRcsProvisioningChangedCallback( + getITelephony().unregisterRcsProvisioningCallback( mSubId, callback.getBinder()); } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); @@ -1506,6 +1509,14 @@ public class ProvisioningManager { /** * Reconfiguration triggered by the RCS application. Most likely cause * is the 403 forbidden to a HTTP request. + * + * <p>When this api is called, the RCS configuration for the associated + * subscription will be removed, and the application which has registered + * {@link RcsProvisioningCallback} may expect to receive + * {@link RcsProvisioningCallback#onConfigurationReset}, then + * {@link RcsProvisioningCallback#onConfigurationChanged} when the new + * RCS configuration is received and notified by + * {@link #notifyRcsAutoConfigurationReceived} */ @RequiresPermission(Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION) public void triggerRcsReconfiguration() { diff --git a/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java b/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java index 5eb75e762fc9..cd1f4c5e9253 100644 --- a/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java +++ b/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java @@ -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; } diff --git a/telephony/java/android/telephony/ims/RcsContactUceCapability.java b/telephony/java/android/telephony/ims/RcsContactUceCapability.java index fe855023f5d0..b28dc27e06e0 100644 --- a/telephony/java/android/telephony/ims/RcsContactUceCapability.java +++ b/telephony/java/android/telephony/ims/RcsContactUceCapability.java @@ -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() { diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java index ce8bd7d8c28e..815c08d120c2 100644 --- a/telephony/java/android/telephony/ims/RcsUceAdapter.java +++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java @@ -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, @@ -549,6 +552,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." * <p> @@ -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 diff --git a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java index 908869beb607..00c91681d9ea 100644 --- a/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java +++ b/telephony/java/android/telephony/ims/stub/RcsCapabilityExchangeImplBase.java @@ -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") @@ -403,6 +405,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> * If this operation succeeds, network response updates should be sent to the framework using diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 6f33a8810699..f74484bd4fd8 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -2283,13 +2283,12 @@ interface ITelephony { /** * Register RCS provisioning callback. */ - void registerRcsProvisioningChangedCallback(int subId, - IRcsConfigCallback callback); + void registerRcsProvisioningCallback(int subId, IRcsConfigCallback callback); /** * Unregister RCS provisioning callback. */ - void unregisterRcsProvisioningChangedCallback(int subId, IRcsConfigCallback callback); + void unregisterRcsProvisioningCallback(int subId, IRcsConfigCallback callback); /** * trigger RCS reconfiguration. diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java index 76243a5799c3..3eda7482117f 100644 --- a/telephony/java/com/android/internal/telephony/RILConstants.java +++ b/telephony/java/com/android/internal/telephony/RILConstants.java @@ -522,8 +522,8 @@ public interface RILConstants { int RIL_REQUEST_GET_SYSTEM_SELECTION_CHANNELS = 219; int RIL_REQUEST_GET_HAL_DEVICE_CAPABILITIES = 220; int RIL_REQUEST_SET_DATA_THROTTLING = 221; - int RIL_REQUEST_SET_ALLOWED_NETWORK_TYPE_BITMAP = 222; - int RIL_REQUEST_GET_ALLOWED_NETWORK_TYPE_BITMAP = 223; + int RIL_REQUEST_SET_ALLOWED_NETWORK_TYPES_BITMAP = 222; + int RIL_REQUEST_GET_ALLOWED_NETWORK_TYPES_BITMAP = 223; /* Responses begin */ int RIL_RESPONSE_ACKNOWLEDGEMENT = 800; |