Loading telephony/java/android/telephony/ims/ImsRcsManager.java +5 −8 Original line number Diff line number Diff line Loading @@ -29,12 +29,10 @@ import android.os.RemoteException; import android.provider.Settings; import android.telephony.AccessNetworkConstants; import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyFrameworkInitializer; import android.telephony.ims.aidl.IImsCapabilityCallback; import android.telephony.ims.aidl.IImsRcsController; import android.telephony.ims.feature.ImsFeature; import android.telephony.ims.feature.RcsFeature; import android.telephony.ims.stub.ImsRegistrationImplBase; import android.util.Log; Loading Loading @@ -77,7 +75,7 @@ public class ImsRcsManager { "android.telephony.ims.action.SHOW_CAPABILITY_DISCOVERY_OPT_IN"; /** * Receives RCS availability status updates from the ImsService. * Receives RCS Feature availability status updates from the ImsService. * * @see #isAvailable(int) * @see #registerRcsAvailabilityCallback(Executor, AvailabilityCallback) Loading @@ -101,8 +99,7 @@ public class ImsRcsManager { long callingIdentity = Binder.clearCallingIdentity(); try { mExecutor.execute(() -> mLocalCallback.onAvailabilityChanged( new RcsFeature.RcsImsCapabilities(config))); mExecutor.execute(() -> mLocalCallback.onAvailabilityChanged(config)); } finally { restoreCallingIdentity(callingIdentity); } Loading Loading @@ -137,7 +134,7 @@ public class ImsRcsManager { * * @param capabilities The new availability of the capabilities. */ public void onAvailabilityChanged(@NonNull RcsFeature.RcsImsCapabilities capabilities) { public void onAvailabilityChanged(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities) { } /**@hide*/ Loading Loading @@ -394,7 +391,7 @@ public class ImsRcsManager { * @hide */ @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isCapable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability, public boolean isCapable(@RcsUceAdapter.RcsImsCapabilityFlag int capability, @ImsRegistrationImplBase.ImsRegistrationTech int radioTech) throws ImsException { IImsRcsController imsRcsController = getIImsRcsController(); if (imsRcsController == null) { Loading Loading @@ -428,7 +425,7 @@ public class ImsRcsManager { * @hide */ @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAvailable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability) public boolean isAvailable(@RcsUceAdapter.RcsImsCapabilityFlag int capability) throws ImsException { IImsRcsController imsRcsController = getIImsRcsController(); if (imsRcsController == null) { Loading telephony/java/android/telephony/ims/RcsContactTerminatedReason.aidl 0 → 100644 +20 −0 Original line number Diff line number Diff line /* * Copyright (c) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.telephony.ims; parcelable RcsContactTerminatedReason; telephony/java/android/telephony/ims/RcsContactTerminatedReason.java 0 → 100644 +75 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.telephony.ims; import android.annotation.NonNull; import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; /** * When the resource for the presence subscribe event has been terminated, the method * SubscribeResponseCallback#onResourceTerminated wil be called with a list of * RcsContactTerminatedReason. * @hide */ public final class RcsContactTerminatedReason implements Parcelable { private final Uri mContactUri; private final String mReason; public RcsContactTerminatedReason(Uri contact, String reason) { mContactUri = contact; mReason = reason; } private RcsContactTerminatedReason(Parcel in) { mContactUri = in.readParcelable(Uri.class.getClassLoader()); mReason = in.readString(); } @Override public void writeToParcel(@NonNull Parcel out, int flags) { out.writeParcelable(mContactUri, flags); out.writeString(mReason); } @Override public int describeContents() { return 0; } public static final @NonNull Creator<RcsContactTerminatedReason> CREATOR = new Creator<RcsContactTerminatedReason>() { @Override public RcsContactTerminatedReason createFromParcel(Parcel in) { return new RcsContactTerminatedReason(in); } @Override public RcsContactTerminatedReason[] newArray(int size) { return new RcsContactTerminatedReason[size]; } }; public Uri getContactUri() { return mContactUri; } public String getReason() { return mReason; } } telephony/java/android/telephony/ims/RcsUceAdapter.java +225 −23 Original line number Diff line number Diff line Loading @@ -46,6 +46,30 @@ import java.util.concurrent.Executor; public class RcsUceAdapter { private static final String TAG = "RcsUceAdapter"; /** * This carrier supports User Capability Exchange as, defined by the framework using * SIP OPTIONS. If set, the RcsFeature should support capability exchange. If not set, this * RcsFeature should not publish capabilities or service capability requests. * @hide */ public static final int CAPABILITY_TYPE_OPTIONS_UCE = 1 << 0; /** * This carrier supports User Capability Exchange as, defined by the framework using a * presence server. If set, the RcsFeature should support capability exchange. If not set, this * RcsFeature should not publish capabilities or service capability requests. * @hide */ public static final int CAPABILITY_TYPE_PRESENCE_UCE = 1 << 1; /**@hide*/ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = "CAPABILITY_TYPE_", value = { CAPABILITY_TYPE_OPTIONS_UCE, CAPABILITY_TYPE_PRESENCE_UCE }) public @interface RcsImsCapabilityFlag {} /** * An unknown error has caused the request to fail. * @hide Loading Loading @@ -106,11 +130,6 @@ public class RcsUceAdapter { * @hide */ public static final int ERROR_LOST_NETWORK = 12; /** * The request has failed because the same request has already been added to the queue. * @hide */ public static final int ERROR_ALREADY_IN_QUEUE = 13; /**@hide*/ @Retention(RetentionPolicy.SOURCE) Loading @@ -125,11 +144,89 @@ public class RcsUceAdapter { ERROR_REQUEST_TOO_LARGE, ERROR_REQUEST_TIMEOUT, ERROR_INSUFFICIENT_MEMORY, ERROR_LOST_NETWORK, ERROR_ALREADY_IN_QUEUE ERROR_LOST_NETWORK }) public @interface ErrorCode {} /** * A capability update has been requested due to the Entity Tag (ETag) expiring. * @hide */ public static final int CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED = 0; /** * A capability update has been requested due to moving to LTE with VoPS disabled. * @hide */ public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED = 1; /** * A capability update has been requested due to moving to LTE with VoPS enabled. * @hide */ public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED = 2; /** * A capability update has been requested due to moving to eHRPD. * @hide */ public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD = 3; /** * A capability update has been requested due to moving to HSPA+. * @hide */ public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_HSPAPLUS = 4; /** * A capability update has been requested due to moving to 3G. * @hide */ public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_3G = 5; /** * A capability update has been requested due to moving to 2G. * @hide */ public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_2G = 6; /** * A capability update has been requested due to moving to WLAN * @hide */ public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN = 7; /** * A capability update has been requested due to moving to IWLAN * @hide */ public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN = 8; /** * 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. * @hide */ 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. * @hide */ public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_ENABLED = 11; /**@hide*/ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = "ERROR_", value = { CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED, CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED, CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED, CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD, CAPABILITY_UPDATE_TRIGGER_MOVE_TO_HSPAPLUS, CAPABILITY_UPDATE_TRIGGER_MOVE_TO_3G, CAPABILITY_UPDATE_TRIGGER_MOVE_TO_2G, CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN, 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_ENABLED }) public @interface StackPublishTriggerType {} /** * The last publish has resulted in a "200 OK" response or the device is using SIP OPTIONS for * UCE. Loading Loading @@ -205,7 +302,7 @@ public class RcsUceAdapter { public void onPublishStateChanged(int publishState) { if (mLocalCallback == null) return; long callingIdentity = Binder.clearCallingIdentity(); final long callingIdentity = Binder.clearCallingIdentity(); try { mExecutor.execute(() -> mLocalCallback.onChanged(publishState)); } finally { Loading Loading @@ -238,38 +335,49 @@ public class RcsUceAdapter { } /** * Provides a one-time callback for the response to a UCE request. After this callback is called * by the framework, the reference to this callback will be discarded on the service side. * A callback for the response to a UCE request. The method * {@link CapabilitiesCallback#onCapabilitiesReceived} will be called zero or more times as the * capabilities are received for each requested contact. * <p> * This request will take a varying amount of time depending on if the contacts requested are * cached or if it requires a network query. The timeout time of these requests can vary * depending on the network, however in poor cases it could take up to a minute for a request * to timeout. In that time only a subset of capabilities may have been retrieved. * <p> * After {@link CapabilitiesCallback#onComplete} or {@link CapabilitiesCallback#onError} has * been called, the reference to this callback will be discarded on the service side. * @see #requestCapabilities(Executor, List, CapabilitiesCallback) * @hide */ public static class CapabilitiesCallback { public interface CapabilitiesCallback { /** * Notify this application that the pending capability request has returned successfully. * Notify this application that the pending capability request has returned successfully * for one or more of the requested contacts. * @param contactCapabilities List of capabilities associated with each contact requested. */ public void onCapabilitiesReceived( @NonNull List<RcsContactUceCapability> contactCapabilities) { void onCapabilitiesReceived(@NonNull List<RcsContactUceCapability> contactCapabilities); } /** * The pending request has completed successfully due to all requested contacts information * being delivered. */ void onComplete(); /** * The pending request has resulted in an error and may need to be retried, depending on the * error code. * @param errorCode The reason for the framework being unable to process the request. */ public void onError(@ErrorCode int errorCode) { } void onError(@ErrorCode int errorCode); } private final Context mContext; private final int mSubId; /** * Not to be instantiated directly, use * {@link ImsRcsManager#getUceAdapter()} to instantiate this manager class. * Not to be instantiated directly, use {@link ImsRcsManager#getUceAdapter()} to instantiate * this manager class. * @hide */ RcsUceAdapter(Context context, int subId) { Loading @@ -280,6 +388,9 @@ 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)} and ensuring * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_OPTIONS_UCE} or Loading @@ -302,7 +413,7 @@ public class RcsUceAdapter { @NonNull List<Uri> contactNumbers, @NonNull CapabilitiesCallback c) throws ImsException { if (c == null) { throw new IllegalArgumentException("Must include a non-null AvailabilityCallback."); throw new IllegalArgumentException("Must include a non-null CapabilitiesCallback."); } if (executor == null) { throw new IllegalArgumentException("Must include a non-null Executor."); Loading @@ -321,7 +432,7 @@ public class RcsUceAdapter { IRcsUceControllerCallback internalCallback = new IRcsUceControllerCallback.Stub() { @Override public void onCapabilitiesReceived(List<RcsContactUceCapability> contactCapabilities) { long callingIdentity = Binder.clearCallingIdentity(); final long callingIdentity = Binder.clearCallingIdentity(); try { executor.execute(() -> c.onCapabilitiesReceived(contactCapabilities)); Loading @@ -330,8 +441,17 @@ public class RcsUceAdapter { } } @Override public void onComplete() { final long callingIdentity = Binder.clearCallingIdentity(); try { executor.execute(() -> c.onComplete()); } finally { restoreCallingIdentity(callingIdentity); } } @Override public void onError(int errorCode) { long callingIdentity = Binder.clearCallingIdentity(); final long callingIdentity = Binder.clearCallingIdentity(); try { executor.execute(() -> c.onError(errorCode)); } finally { Loading @@ -350,6 +470,88 @@ public class RcsUceAdapter { } } /** * Ignore the device cache and perform a capability discovery for one contact, also called * "availability fetch." * <p> * This will always perform a query to the network as long as requests are over the carrier * availability fetch throttling threshold. If too many network requests are sent too quickly, * #ERROR_TOO_MANY_REQUESTS will be returned. * * <p> * Be sure to check the availability of this feature using * {@link ImsRcsManager#isAvailable(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 contactNumber The contact of the capabilities is being requested for. * @param c A one-time callback for when the request for capabilities completes or there is * an error processing the request. * @hide */ @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) public void requestNetworkAvailability(@NonNull @CallbackExecutor Executor executor, @NonNull Uri contactNumber, @NonNull CapabilitiesCallback c) throws ImsException { if (executor == null) { throw new IllegalArgumentException("Must include a non-null Executor."); } if (contactNumber == null) { throw new IllegalArgumentException("Must include non-null contact number."); } if (c == null) { throw new IllegalArgumentException("Must include a non-null CapabilitiesCallback."); } IImsRcsController imsRcsController = getIImsRcsController(); if (imsRcsController == null) { Log.e(TAG, "requestNetworkAvailability: IImsRcsController is null"); throw new ImsException("Cannot 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) { final long callingIdentity = Binder.clearCallingIdentity(); try { executor.execute(() -> c.onError(errorCode)); } finally { restoreCallingIdentity(callingIdentity); } } }; try { imsRcsController.requestNetworkAvailability(mSubId, mContext.getOpPackageName(), mContext.getAttributionTag(), contactNumber, internalCallback); } catch (RemoteException e) { Log.e(TAG, "Error calling IImsRcsController#requestNetworkAvailability", e); throw new ImsException("Remote IMS Service is not available", ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); } } /** * Gets the last publish result from the UCE service if the device is using an RCS presence * server. Loading telephony/java/android/telephony/ims/aidl/ICapabilityExchangeEventListener.aidl 0 → 100644 +75 −0 Original line number Diff line number Diff line /* * 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.net.Uri; import android.telephony.ims.aidl.IOptionsRequestCallback; import java.util.List; /** * Listener interface for the ImsService to use to notify the framework of UCE events. * {@hide} */ 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); /** * 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(); /** * 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, in List<String> remoteCapabilities, IOptionsRequestCallback cb); } Loading
telephony/java/android/telephony/ims/ImsRcsManager.java +5 −8 Original line number Diff line number Diff line Loading @@ -29,12 +29,10 @@ import android.os.RemoteException; import android.provider.Settings; import android.telephony.AccessNetworkConstants; import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyFrameworkInitializer; import android.telephony.ims.aidl.IImsCapabilityCallback; import android.telephony.ims.aidl.IImsRcsController; import android.telephony.ims.feature.ImsFeature; import android.telephony.ims.feature.RcsFeature; import android.telephony.ims.stub.ImsRegistrationImplBase; import android.util.Log; Loading Loading @@ -77,7 +75,7 @@ public class ImsRcsManager { "android.telephony.ims.action.SHOW_CAPABILITY_DISCOVERY_OPT_IN"; /** * Receives RCS availability status updates from the ImsService. * Receives RCS Feature availability status updates from the ImsService. * * @see #isAvailable(int) * @see #registerRcsAvailabilityCallback(Executor, AvailabilityCallback) Loading @@ -101,8 +99,7 @@ public class ImsRcsManager { long callingIdentity = Binder.clearCallingIdentity(); try { mExecutor.execute(() -> mLocalCallback.onAvailabilityChanged( new RcsFeature.RcsImsCapabilities(config))); mExecutor.execute(() -> mLocalCallback.onAvailabilityChanged(config)); } finally { restoreCallingIdentity(callingIdentity); } Loading Loading @@ -137,7 +134,7 @@ public class ImsRcsManager { * * @param capabilities The new availability of the capabilities. */ public void onAvailabilityChanged(@NonNull RcsFeature.RcsImsCapabilities capabilities) { public void onAvailabilityChanged(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities) { } /**@hide*/ Loading Loading @@ -394,7 +391,7 @@ public class ImsRcsManager { * @hide */ @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isCapable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability, public boolean isCapable(@RcsUceAdapter.RcsImsCapabilityFlag int capability, @ImsRegistrationImplBase.ImsRegistrationTech int radioTech) throws ImsException { IImsRcsController imsRcsController = getIImsRcsController(); if (imsRcsController == null) { Loading Loading @@ -428,7 +425,7 @@ public class ImsRcsManager { * @hide */ @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAvailable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability) public boolean isAvailable(@RcsUceAdapter.RcsImsCapabilityFlag int capability) throws ImsException { IImsRcsController imsRcsController = getIImsRcsController(); if (imsRcsController == null) { Loading
telephony/java/android/telephony/ims/RcsContactTerminatedReason.aidl 0 → 100644 +20 −0 Original line number Diff line number Diff line /* * Copyright (c) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.telephony.ims; parcelable RcsContactTerminatedReason;
telephony/java/android/telephony/ims/RcsContactTerminatedReason.java 0 → 100644 +75 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.telephony.ims; import android.annotation.NonNull; import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; /** * When the resource for the presence subscribe event has been terminated, the method * SubscribeResponseCallback#onResourceTerminated wil be called with a list of * RcsContactTerminatedReason. * @hide */ public final class RcsContactTerminatedReason implements Parcelable { private final Uri mContactUri; private final String mReason; public RcsContactTerminatedReason(Uri contact, String reason) { mContactUri = contact; mReason = reason; } private RcsContactTerminatedReason(Parcel in) { mContactUri = in.readParcelable(Uri.class.getClassLoader()); mReason = in.readString(); } @Override public void writeToParcel(@NonNull Parcel out, int flags) { out.writeParcelable(mContactUri, flags); out.writeString(mReason); } @Override public int describeContents() { return 0; } public static final @NonNull Creator<RcsContactTerminatedReason> CREATOR = new Creator<RcsContactTerminatedReason>() { @Override public RcsContactTerminatedReason createFromParcel(Parcel in) { return new RcsContactTerminatedReason(in); } @Override public RcsContactTerminatedReason[] newArray(int size) { return new RcsContactTerminatedReason[size]; } }; public Uri getContactUri() { return mContactUri; } public String getReason() { return mReason; } }
telephony/java/android/telephony/ims/RcsUceAdapter.java +225 −23 Original line number Diff line number Diff line Loading @@ -46,6 +46,30 @@ import java.util.concurrent.Executor; public class RcsUceAdapter { private static final String TAG = "RcsUceAdapter"; /** * This carrier supports User Capability Exchange as, defined by the framework using * SIP OPTIONS. If set, the RcsFeature should support capability exchange. If not set, this * RcsFeature should not publish capabilities or service capability requests. * @hide */ public static final int CAPABILITY_TYPE_OPTIONS_UCE = 1 << 0; /** * This carrier supports User Capability Exchange as, defined by the framework using a * presence server. If set, the RcsFeature should support capability exchange. If not set, this * RcsFeature should not publish capabilities or service capability requests. * @hide */ public static final int CAPABILITY_TYPE_PRESENCE_UCE = 1 << 1; /**@hide*/ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = "CAPABILITY_TYPE_", value = { CAPABILITY_TYPE_OPTIONS_UCE, CAPABILITY_TYPE_PRESENCE_UCE }) public @interface RcsImsCapabilityFlag {} /** * An unknown error has caused the request to fail. * @hide Loading Loading @@ -106,11 +130,6 @@ public class RcsUceAdapter { * @hide */ public static final int ERROR_LOST_NETWORK = 12; /** * The request has failed because the same request has already been added to the queue. * @hide */ public static final int ERROR_ALREADY_IN_QUEUE = 13; /**@hide*/ @Retention(RetentionPolicy.SOURCE) Loading @@ -125,11 +144,89 @@ public class RcsUceAdapter { ERROR_REQUEST_TOO_LARGE, ERROR_REQUEST_TIMEOUT, ERROR_INSUFFICIENT_MEMORY, ERROR_LOST_NETWORK, ERROR_ALREADY_IN_QUEUE ERROR_LOST_NETWORK }) public @interface ErrorCode {} /** * A capability update has been requested due to the Entity Tag (ETag) expiring. * @hide */ public static final int CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED = 0; /** * A capability update has been requested due to moving to LTE with VoPS disabled. * @hide */ public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED = 1; /** * A capability update has been requested due to moving to LTE with VoPS enabled. * @hide */ public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED = 2; /** * A capability update has been requested due to moving to eHRPD. * @hide */ public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD = 3; /** * A capability update has been requested due to moving to HSPA+. * @hide */ public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_HSPAPLUS = 4; /** * A capability update has been requested due to moving to 3G. * @hide */ public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_3G = 5; /** * A capability update has been requested due to moving to 2G. * @hide */ public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_2G = 6; /** * A capability update has been requested due to moving to WLAN * @hide */ public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN = 7; /** * A capability update has been requested due to moving to IWLAN * @hide */ public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN = 8; /** * 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. * @hide */ 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. * @hide */ public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_NR5G_VOPS_ENABLED = 11; /**@hide*/ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = "ERROR_", value = { CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED, CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED, CAPABILITY_UPDATE_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED, CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD, CAPABILITY_UPDATE_TRIGGER_MOVE_TO_HSPAPLUS, CAPABILITY_UPDATE_TRIGGER_MOVE_TO_3G, CAPABILITY_UPDATE_TRIGGER_MOVE_TO_2G, CAPABILITY_UPDATE_TRIGGER_MOVE_TO_WLAN, 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_ENABLED }) public @interface StackPublishTriggerType {} /** * The last publish has resulted in a "200 OK" response or the device is using SIP OPTIONS for * UCE. Loading Loading @@ -205,7 +302,7 @@ public class RcsUceAdapter { public void onPublishStateChanged(int publishState) { if (mLocalCallback == null) return; long callingIdentity = Binder.clearCallingIdentity(); final long callingIdentity = Binder.clearCallingIdentity(); try { mExecutor.execute(() -> mLocalCallback.onChanged(publishState)); } finally { Loading Loading @@ -238,38 +335,49 @@ public class RcsUceAdapter { } /** * Provides a one-time callback for the response to a UCE request. After this callback is called * by the framework, the reference to this callback will be discarded on the service side. * A callback for the response to a UCE request. The method * {@link CapabilitiesCallback#onCapabilitiesReceived} will be called zero or more times as the * capabilities are received for each requested contact. * <p> * This request will take a varying amount of time depending on if the contacts requested are * cached or if it requires a network query. The timeout time of these requests can vary * depending on the network, however in poor cases it could take up to a minute for a request * to timeout. In that time only a subset of capabilities may have been retrieved. * <p> * After {@link CapabilitiesCallback#onComplete} or {@link CapabilitiesCallback#onError} has * been called, the reference to this callback will be discarded on the service side. * @see #requestCapabilities(Executor, List, CapabilitiesCallback) * @hide */ public static class CapabilitiesCallback { public interface CapabilitiesCallback { /** * Notify this application that the pending capability request has returned successfully. * Notify this application that the pending capability request has returned successfully * for one or more of the requested contacts. * @param contactCapabilities List of capabilities associated with each contact requested. */ public void onCapabilitiesReceived( @NonNull List<RcsContactUceCapability> contactCapabilities) { void onCapabilitiesReceived(@NonNull List<RcsContactUceCapability> contactCapabilities); } /** * The pending request has completed successfully due to all requested contacts information * being delivered. */ void onComplete(); /** * The pending request has resulted in an error and may need to be retried, depending on the * error code. * @param errorCode The reason for the framework being unable to process the request. */ public void onError(@ErrorCode int errorCode) { } void onError(@ErrorCode int errorCode); } private final Context mContext; private final int mSubId; /** * Not to be instantiated directly, use * {@link ImsRcsManager#getUceAdapter()} to instantiate this manager class. * Not to be instantiated directly, use {@link ImsRcsManager#getUceAdapter()} to instantiate * this manager class. * @hide */ RcsUceAdapter(Context context, int subId) { Loading @@ -280,6 +388,9 @@ 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)} and ensuring * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_OPTIONS_UCE} or Loading @@ -302,7 +413,7 @@ public class RcsUceAdapter { @NonNull List<Uri> contactNumbers, @NonNull CapabilitiesCallback c) throws ImsException { if (c == null) { throw new IllegalArgumentException("Must include a non-null AvailabilityCallback."); throw new IllegalArgumentException("Must include a non-null CapabilitiesCallback."); } if (executor == null) { throw new IllegalArgumentException("Must include a non-null Executor."); Loading @@ -321,7 +432,7 @@ public class RcsUceAdapter { IRcsUceControllerCallback internalCallback = new IRcsUceControllerCallback.Stub() { @Override public void onCapabilitiesReceived(List<RcsContactUceCapability> contactCapabilities) { long callingIdentity = Binder.clearCallingIdentity(); final long callingIdentity = Binder.clearCallingIdentity(); try { executor.execute(() -> c.onCapabilitiesReceived(contactCapabilities)); Loading @@ -330,8 +441,17 @@ public class RcsUceAdapter { } } @Override public void onComplete() { final long callingIdentity = Binder.clearCallingIdentity(); try { executor.execute(() -> c.onComplete()); } finally { restoreCallingIdentity(callingIdentity); } } @Override public void onError(int errorCode) { long callingIdentity = Binder.clearCallingIdentity(); final long callingIdentity = Binder.clearCallingIdentity(); try { executor.execute(() -> c.onError(errorCode)); } finally { Loading @@ -350,6 +470,88 @@ public class RcsUceAdapter { } } /** * Ignore the device cache and perform a capability discovery for one contact, also called * "availability fetch." * <p> * This will always perform a query to the network as long as requests are over the carrier * availability fetch throttling threshold. If too many network requests are sent too quickly, * #ERROR_TOO_MANY_REQUESTS will be returned. * * <p> * Be sure to check the availability of this feature using * {@link ImsRcsManager#isAvailable(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 contactNumber The contact of the capabilities is being requested for. * @param c A one-time callback for when the request for capabilities completes or there is * an error processing the request. * @hide */ @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) public void requestNetworkAvailability(@NonNull @CallbackExecutor Executor executor, @NonNull Uri contactNumber, @NonNull CapabilitiesCallback c) throws ImsException { if (executor == null) { throw new IllegalArgumentException("Must include a non-null Executor."); } if (contactNumber == null) { throw new IllegalArgumentException("Must include non-null contact number."); } if (c == null) { throw new IllegalArgumentException("Must include a non-null CapabilitiesCallback."); } IImsRcsController imsRcsController = getIImsRcsController(); if (imsRcsController == null) { Log.e(TAG, "requestNetworkAvailability: IImsRcsController is null"); throw new ImsException("Cannot 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) { final long callingIdentity = Binder.clearCallingIdentity(); try { executor.execute(() -> c.onError(errorCode)); } finally { restoreCallingIdentity(callingIdentity); } } }; try { imsRcsController.requestNetworkAvailability(mSubId, mContext.getOpPackageName(), mContext.getAttributionTag(), contactNumber, internalCallback); } catch (RemoteException e) { Log.e(TAG, "Error calling IImsRcsController#requestNetworkAvailability", e); throw new ImsException("Remote IMS Service is not available", ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); } } /** * Gets the last publish result from the UCE service if the device is using an RCS presence * server. Loading
telephony/java/android/telephony/ims/aidl/ICapabilityExchangeEventListener.aidl 0 → 100644 +75 −0 Original line number Diff line number Diff line /* * 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.net.Uri; import android.telephony.ims.aidl.IOptionsRequestCallback; import java.util.List; /** * Listener interface for the ImsService to use to notify the framework of UCE events. * {@hide} */ 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); /** * 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(); /** * 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, in List<String> remoteCapabilities, IOptionsRequestCallback cb); }