Loading src/java/com/android/ims/RcsFeatureConnection.java +15 −4 Original line number Diff line number Diff line Loading @@ -21,19 +21,19 @@ import android.content.Context; import android.net.Uri; import android.os.IBinder; import android.os.RemoteException; import android.telephony.TelephonyManager; import android.telephony.ims.RcsContactUceCapability; import android.telephony.ims.aidl.ICapabilityExchangeEventListener; import android.telephony.ims.aidl.IImsCapabilityCallback; import android.telephony.ims.aidl.IImsConfig; import android.telephony.ims.aidl.IImsRcsFeature; import android.telephony.ims.aidl.IImsRegistration; import android.telephony.ims.aidl.IImsRegistrationCallback; import android.telephony.ims.aidl.IPublishResponseCallback; import android.telephony.ims.aidl.IRcsFeatureListener; import android.telephony.ims.aidl.ISipTransport; import android.telephony.ims.feature.CapabilityChangeRequest; import android.telephony.ims.feature.ImsFeature; import com.android.ims.rcs.uce.RcsCapabilityExchangeImplAdapter.PublishResponseCallback; import com.android.internal.annotations.VisibleForTesting; import com.android.telephony.Rlog; Loading Loading @@ -225,9 +225,20 @@ public class RcsFeatureConnection extends FeatureConnection { } } public void requestPublication(String pidfXml, PublishResponseCallback responseCallback) public void setCapabilityExchangeEventListener(ICapabilityExchangeEventListener listener) throws RemoteException{ // TODO: add the new API: requestPublication synchronized (mLock) { checkServiceIsReady(); getServiceInterface(mBinder).setCapabilityExchangeEventListener(listener); } } public void requestPublication(String pidfXml, IPublishResponseCallback responseCallback) throws RemoteException { synchronized (mLock) { checkServiceIsReady(); getServiceInterface(mBinder).publishCapabilities(pidfXml, responseCallback); } } public void requestCapabilities(List<Uri> uris, int taskId) throws RemoteException { Loading src/java/com/android/ims/RcsFeatureManager.java +8 −2 Original line number Diff line number Diff line Loading @@ -30,10 +30,12 @@ import android.telephony.ims.ImsException; import android.telephony.ims.ImsService; import android.telephony.ims.RcsContactUceCapability; import android.telephony.ims.RegistrationManager; import android.telephony.ims.aidl.ICapabilityExchangeEventListener; import android.telephony.ims.aidl.IImsCapabilityCallback; import android.telephony.ims.aidl.IImsRcsController; import android.telephony.ims.aidl.IImsRcsFeature; import android.telephony.ims.aidl.IImsRegistrationCallback; import android.telephony.ims.aidl.IPublishResponseCallback; import android.telephony.ims.aidl.IRcsFeatureListener; import android.telephony.ims.aidl.ISipTransport; import android.telephony.ims.feature.CapabilityChangeRequest; Loading @@ -47,7 +49,6 @@ import android.telephony.ims.stub.RcsSipOptionsImplBase; import android.util.Log; import com.android.ims.internal.IImsServiceFeatureCallback; import com.android.ims.rcs.uce.RcsCapabilityExchangeImplAdapter.PublishResponseCallback; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.ITelephony; import com.android.telephony.Rlog; Loading Loading @@ -450,7 +451,12 @@ public class RcsFeatureManager implements FeatureUpdates { mRcsFeatureConnection.requestPublication(capabilities, taskId); } public void requestPublication(String pidfXml, PublishResponseCallback responseCallback) public void setCapabilityExchangeEventListener(ICapabilityExchangeEventListener listener) throws RemoteException { mRcsFeatureConnection.setCapabilityExchangeEventListener(listener); } public void requestPublication(String pidfXml, IPublishResponseCallback responseCallback) throws RemoteException { mRcsFeatureConnection.requestPublication(pidfXml, responseCallback); } Loading src/java/com/android/ims/rcs/uce/RcsCapabilityExchangeImplAdapter.javadeleted 100644 → 0 +0 −118 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 com.android.ims.rcs.uce; import android.annotation.NonNull; import android.annotation.Nullable; import android.net.Uri; import android.telephony.ims.ImsException; import java.util.List; /** * The adapter class of RcsCapabilityExchangeImplBase */ public class RcsCapabilityExchangeImplAdapter { /** Service is unknown. */ public static final int COMMAND_CODE_SERVICE_UNKNOWN = 0; /** The command failed with an unknown error. */ public static final int COMMAND_CODE_GENERIC_FAILURE = 1; /** Invalid parameter(s). */ public static final int COMMAND_CODE_INVALID_PARAM = 2; /** Fetch error. */ public static final int COMMAND_CODE_FETCH_ERROR = 3; /** Request timed out. */ public static final int COMMAND_CODE_REQUEST_TIMEOUT = 4; /** Failure due to insufficient memory available. */ public static final int COMMAND_CODE_INSUFFICIENT_MEMORY = 5; /** Network connection is lost. */ public static final int COMMAND_CODE_LOST_NETWORK_CONNECTION = 6; /** Requested feature/resource is not supported. */ public static final int COMMAND_CODE_NOT_SUPPORTED = 7; /** Contact or resource is not found. */ public static final int COMMAND_CODE_NOT_FOUND = 8; /** Service is not available. */ public static final int COMMAND_CODE_SERVICE_UNAVAILABLE = 9; /** Command resulted in no change in state, ignoring. */ public static final int COMMAND_CODE_NO_CHANGE = 10; /** * The adapter class of the interface PublishResponseCallback */ public interface PublishResponseCallback { /** * Notify the framework that the command associated with this callback has failed. */ void onCommandError(int code) throws ImsException; /** * Provide the framework with a subsequent network response update to * {@link #publishCapabilities(RcsContactUceCapability, int)}. */ void onNetworkResponse(int code, @NonNull String reason) throws ImsException; } /** * The adapter class of the interface OptionsResponseCallback */ public interface OptionsResponseCallback { /** * Notify the framework that the command associated with this callback has * failed. */ void onCommandError(int code) throws ImsException; /** * Send the response of a SIP OPTIONS capability exchange to the framework. */ void onNetworkResponse(int code, @NonNull String reason, @Nullable List<String> theirCaps) throws ImsException; } /** * The adapter class of the interface SubscribeResponseCallback */ public interface SubscribeResponseCallback { /** * Notify the framework that the command associated with this callback has failed. */ void onCommandError(int code) throws ImsException; /** * Notify the framework of the response to the SUBSCRIBE request from * {@link #subscribeForCapabilities(RcsContactUceCapability, int)}. */ void onNetworkResponse(int code, @NonNull String reason) throws ImsException; /** * Provides the framework with latest XML PIDF documents included in the * network response for the requested contacts' capabilities requested by the * Framework using {@link #requestCapabilities(List, int)}. This should be * called every time a new NOTIFY event is received with new capability * information. */ void onNotifyCapabilitiesUpdate(@NonNull List<String> pidfXmls) throws ImsException; /** * The subscription associated with a previous #requestCapabilities operation * has been terminated. This will mostly be due to the subscription expiring, * but may also happen due to an error. */ void onTerminated(String reason, String retryAfter) throws ImsException; } } src/java/com/android/ims/rcs/uce/UceController.java +126 −26 Original line number Diff line number Diff line Loading @@ -21,25 +21,32 @@ import android.content.Context; import android.net.Uri; import android.os.HandlerThread; import android.os.Looper; import android.os.RemoteException; import android.telephony.ims.RcsContactUceCapability; import android.telephony.ims.RcsUceAdapter; import android.telephony.ims.RcsUceAdapter.CapabilitiesCallback; import android.telephony.ims.RcsUceAdapter.PublishState; import android.telephony.ims.RcsUceAdapter.StackPublishTriggerType; import android.telephony.ims.RcsUceAdapter.PublishStateCallback; import android.telephony.ims.aidl.ICapabilityExchangeEventListener; import android.telephony.ims.aidl.IOptionsRequestCallback; import android.telephony.ims.aidl.IOptionsResponseCallback; import android.telephony.ims.aidl.IRcsUceControllerCallback; import android.telephony.ims.aidl.IRcsUcePublishStateCallback; import android.util.Log; import com.android.ims.RcsFeatureManager; import com.android.ims.rcs.uce.eab.EabCapabilityResult; import com.android.ims.rcs.uce.eab.EabController; import com.android.ims.rcs.uce.eab.EabControllerImpl; import com.android.ims.rcs.uce.options.OptionsController; import com.android.ims.rcs.uce.options.OptionsControllerImpl; import com.android.ims.rcs.uce.presence.publish.PublishController; import com.android.ims.rcs.uce.presence.publish.PublishControllerImpl; import com.android.ims.rcs.uce.presence.subscribe.SubscribeController; import com.android.ims.rcs.uce.presence.subscribe.SubscribeControllerImpl; import com.android.internal.annotations.VisibleForTesting; import java.util.Arrays; import java.util.List; import java.util.Objects; /** * The UceController will manage the RCS UCE requests on a per subscription basis. When it receives Loading Loading @@ -80,14 +87,14 @@ public class UceController { */ void requestCapabilitiesByOptions(@NonNull Uri contactUri, @NonNull RcsContactUceCapability ownCapabilities, @NonNull RcsCapabilityExchangeImplAdapter.OptionsResponseCallback callback); @NonNull IOptionsResponseCallback callback); /** * The method is called when the given contacts' capabilities are expired and need to be * refreshed. */ void refreshCapabilities(@NonNull List<Uri> contactNumbers, @NonNull CapabilitiesCallback callback); @NonNull IRcsUceControllerCallback callback) throws RemoteException; /** * The method is called when the EabController and the PublishController want to receive Loading @@ -109,6 +116,9 @@ public class UceController { UceRequestTaskManager createTaskManager(Context context, int subId, Looper looper); } private RequestTaskManagerFactory mTaskManagerFactory = (context, subId, looper) -> new UceRequestTaskManager(context, subId, looper); /** * Used to inject Controller instances for testing. */ Loading Loading @@ -138,31 +148,61 @@ public class UceController { UceControllerCallback c, Looper looper); } private ControllerFactory mControllerFactory = new ControllerFactory() { @Override public EabController createEabController(Context context, int subId, UceControllerCallback c, Looper looper) { return new EabControllerImpl(context, subId, c, looper); } @Override public PublishController createPublishController(Context context, int subId, Looper looper) { return new PublishControllerImpl(context, subId, looper); } @Override public SubscribeController createSubscribeController(Context context, int subId, UceControllerCallback c, Looper looper) { return new SubscribeControllerImpl(context, subId, c, looper); } @Override public OptionsController createOptionsController(Context context, int subId, UceControllerCallback c, Looper looper) { return new OptionsControllerImpl(context, subId, c, looper); } }; private final int mSubId; private final Context mContext; private volatile boolean mIsRcsConnected; private volatile boolean mIsDestroyedFlag; private Looper mLooper; private UceRequestTaskManager mTaskManager; private final RequestTaskManagerFactory mTaskManagerFactory; private EabController mEabController; private PublishController mPublishController; private SubscribeController mSubscribeController; private OptionsController mOptionsController; private final ControllerFactory mControllerFactory; private UceRequestTaskManager mTaskManager; public UceController(Context context, int subId, ControllerFactory controllerFactory, RequestTaskManagerFactory taskManagerFactory) { public UceController(Context context, int subId) { mSubId = subId; mContext = context; logi("create"); initLooper(); initRequestTaskManager(); initControllers(); } @VisibleForTesting public UceController(Context context, int subId, ControllerFactory controllerFactory, RequestTaskManagerFactory taskManagerFactory) { mSubId = subId; mContext = context; mControllerFactory = controllerFactory; mTaskManagerFactory = taskManagerFactory; initLooper(); initRequestTaskManager(); initControllers(); Loading Loading @@ -200,6 +240,12 @@ public class UceController { mPublishController.onRcsConnected(manager); mSubscribeController.onRcsConnected(manager); mOptionsController.onRcsConnected(manager); try { manager.setCapabilityExchangeEventListener(mCapabilityEventListener); } catch (RemoteException e) { logw("Set capability event listener error: " + e.getMessage()); } } /** Loading Loading @@ -230,7 +276,10 @@ public class UceController { mLooper.quit(); } // The implementation of the interface UceControllerCallback. /* * The implementation of the interface UceControllerCallback. These methods are called by other * controllers. */ private UceControllerCallback mCtrlCallback = new UceControllerCallback() { @Override public EabCapabilityResult getCapabilitiesFromCache(List<Uri> uris) { Loading @@ -253,14 +302,15 @@ public class UceController { } @Override public void requestCapabilitiesByOptions(Uri uri, RcsContactUceCapability ownCapabilities, RcsCapabilityExchangeImplAdapter.OptionsResponseCallback callback) { public void requestCapabilitiesByOptions(@NonNull Uri uri, @NonNull RcsContactUceCapability ownCapabilities, @NonNull IOptionsResponseCallback callback) { mOptionsController.sendCapabilitiesRequest(uri, ownCapabilities, callback); } @Override public void refreshCapabilities(@NonNull List<Uri> contactNumbers, @NonNull CapabilitiesCallback callback) { @NonNull IRcsUceControllerCallback callback) throws RemoteException{ logd("refreshCapabilities: " + contactNumbers.size()); UceController.this.requestCapabilities(contactNumbers, callback); } Loading @@ -283,12 +333,44 @@ public class UceController { mCtrlCallback = callback; } /* * Setup the listener to listen to the requests and updates from ImsService. */ private ICapabilityExchangeEventListener mCapabilityEventListener = new ICapabilityExchangeEventListener.Stub() { @Override public void onRequestPublishCapabilities( @StackPublishTriggerType int publishTriggerType) { onRequestPublishCapabilitiesFromService(publishTriggerType); } @Override public void onUnpublish() { UceController.this.onUnpublish(); } @Override public void onRemoteCapabilityRequest(Uri contactUri, List<String> remoteCapabilities, IOptionsRequestCallback cb) { retrieveOptionsCapabilitiesForRemote(contactUri, remoteCapabilities, cb); } }; /** * Request to get the contacts' capabilities. This method will retrieve the capabilities from * the cache If the capabilities are out of date, it will trigger another request to get the * latest contact's capabilities from the carrier network. */ public void requestCapabilities(@NonNull List<Uri> uriList, @NonNull CapabilitiesCallback c) { public void requestCapabilities(@NonNull List<Uri> uriList, @NonNull IRcsUceControllerCallback c) throws RemoteException { if (uriList == null || c == null) { logw("requestCapabilities: parameter is empty"); if (c != null) { c.onError(RcsUceAdapter.ERROR_GENERIC_FAILURE); } return; } if (isUnavailable()) { logw("requestCapabilities: controller is unavailable"); c.onError(RcsUceAdapter.ERROR_GENERIC_FAILURE); Loading @@ -296,7 +378,7 @@ public class UceController { } // Trigger the capabilities request task logd("requestCapabilities"); logd("requestCapabilities: " + uriList.size()); mTaskManager.triggerCapabilityRequestTask(mCtrlCallback, uriList, c); } Loading @@ -305,7 +387,16 @@ public class UceController { * the capability in the availability cache is expired then it will retrieve the capability * from the carrier network. */ public void requestAvailability(@NonNull Uri uri, @NonNull CapabilitiesCallback c) { public void requestAvailability(@NonNull Uri uri, @NonNull IRcsUceControllerCallback c) throws RemoteException{ if (uri == null || c == null) { logw("requestCapabilities: parameter is empty"); if (c != null) { c.onError(RcsUceAdapter.ERROR_GENERIC_FAILURE); } return; } if (isUnavailable()) { logw("requestAvailability: controller is unavailable"); c.onError(RcsUceAdapter.ERROR_GENERIC_FAILURE); Loading @@ -320,9 +411,9 @@ public class UceController { /** * Publish the device's capabilities. This request is triggered from the ImsService. */ public void onRequestPublishCapabilitiesFromService() { logd("onRequestPublishCapabilitiesFromService"); mPublishController.requestPublishCapabilitiesFromService(); public void onRequestPublishCapabilitiesFromService(@StackPublishTriggerType int triggerType) { logd("onRequestPublishCapabilitiesFromService: " + triggerType); mPublishController.requestPublishCapabilitiesFromService(triggerType); } /** Loading @@ -339,8 +430,7 @@ public class UceController { * capabilities to the remote side. */ public void retrieveOptionsCapabilitiesForRemote(@NonNull Uri contactUri, @NonNull List<String> remoteCapabilities, @NonNull CapabilityExchangeListenerAdapter.OptionsRequestCallback c) { @NonNull List<String> remoteCapabilities, @NonNull IOptionsRequestCallback c) { logd("retrieveOptionsCapabilitiesForRemote"); mOptionsController.retrieveCapabilitiesForRemote(contactUri, remoteCapabilities, c); } Loading @@ -366,11 +456,21 @@ public class UceController { return mPublishController.getUcePublishState(); } @VisibleForTesting public void setRequestTaskManagerFactory(RequestTaskManagerFactory factory) { mTaskManagerFactory = factory; } @VisibleForTesting public void setControllerFactory(ControllerFactory factory) { mControllerFactory = factory; } public int getSubId() { return mSubId; } private boolean isUnavailable() { public boolean isUnavailable() { if (!mIsRcsConnected || mIsDestroyedFlag) { return true; } Loading src/java/com/android/ims/rcs/uce/UceRequestTaskManager.java +26 −7 Original line number Diff line number Diff line Loading @@ -16,8 +16,10 @@ package com.android.ims.rcs.uce; import android.content.Context; import android.net.Uri; import android.telephony.ims.RcsUceAdapter; import android.os.Looper; import android.telephony.ims.aidl.IRcsUceControllerCallback; import com.android.ims.rcs.uce.UceController.UceControllerCallback; Loading @@ -26,20 +28,37 @@ import java.util.List; /** * The interface of managing the capability request and the availability request. */ public interface UceRequestTaskManager { public class UceRequestTaskManager { private final Context mContext; private final int mSubId; private final Looper mLooper; public UceRequestTaskManager(Context context, int subId, Looper looper) { mContext = context; mSubId = subId; mLooper = looper; } /** * Trigger the capability request task. */ void triggerCapabilityRequestTask(UceControllerCallback controller, List<Uri> uriList, RcsUceAdapter.CapabilitiesCallback callback); public void triggerCapabilityRequestTask(UceControllerCallback controller, List<Uri> uriList, IRcsUceControllerCallback callback) { // TODO: Implement this method } /** * Trigger the availability request task. */ void triggerAvailabilityRequestTask(UceControllerCallback controller, Uri uri, RcsUceAdapter.CapabilitiesCallback callback); public void triggerAvailabilityRequestTask(UceControllerCallback controller, Uri uri, IRcsUceControllerCallback callback) { // TODO: Implement this method } /** * Notify the task manager to destroy. */ void onDestroy(); public void onDestroy() { // TODO: Implement this method } } Loading
src/java/com/android/ims/RcsFeatureConnection.java +15 −4 Original line number Diff line number Diff line Loading @@ -21,19 +21,19 @@ import android.content.Context; import android.net.Uri; import android.os.IBinder; import android.os.RemoteException; import android.telephony.TelephonyManager; import android.telephony.ims.RcsContactUceCapability; import android.telephony.ims.aidl.ICapabilityExchangeEventListener; import android.telephony.ims.aidl.IImsCapabilityCallback; import android.telephony.ims.aidl.IImsConfig; import android.telephony.ims.aidl.IImsRcsFeature; import android.telephony.ims.aidl.IImsRegistration; import android.telephony.ims.aidl.IImsRegistrationCallback; import android.telephony.ims.aidl.IPublishResponseCallback; import android.telephony.ims.aidl.IRcsFeatureListener; import android.telephony.ims.aidl.ISipTransport; import android.telephony.ims.feature.CapabilityChangeRequest; import android.telephony.ims.feature.ImsFeature; import com.android.ims.rcs.uce.RcsCapabilityExchangeImplAdapter.PublishResponseCallback; import com.android.internal.annotations.VisibleForTesting; import com.android.telephony.Rlog; Loading Loading @@ -225,9 +225,20 @@ public class RcsFeatureConnection extends FeatureConnection { } } public void requestPublication(String pidfXml, PublishResponseCallback responseCallback) public void setCapabilityExchangeEventListener(ICapabilityExchangeEventListener listener) throws RemoteException{ // TODO: add the new API: requestPublication synchronized (mLock) { checkServiceIsReady(); getServiceInterface(mBinder).setCapabilityExchangeEventListener(listener); } } public void requestPublication(String pidfXml, IPublishResponseCallback responseCallback) throws RemoteException { synchronized (mLock) { checkServiceIsReady(); getServiceInterface(mBinder).publishCapabilities(pidfXml, responseCallback); } } public void requestCapabilities(List<Uri> uris, int taskId) throws RemoteException { Loading
src/java/com/android/ims/RcsFeatureManager.java +8 −2 Original line number Diff line number Diff line Loading @@ -30,10 +30,12 @@ import android.telephony.ims.ImsException; import android.telephony.ims.ImsService; import android.telephony.ims.RcsContactUceCapability; import android.telephony.ims.RegistrationManager; import android.telephony.ims.aidl.ICapabilityExchangeEventListener; import android.telephony.ims.aidl.IImsCapabilityCallback; import android.telephony.ims.aidl.IImsRcsController; import android.telephony.ims.aidl.IImsRcsFeature; import android.telephony.ims.aidl.IImsRegistrationCallback; import android.telephony.ims.aidl.IPublishResponseCallback; import android.telephony.ims.aidl.IRcsFeatureListener; import android.telephony.ims.aidl.ISipTransport; import android.telephony.ims.feature.CapabilityChangeRequest; Loading @@ -47,7 +49,6 @@ import android.telephony.ims.stub.RcsSipOptionsImplBase; import android.util.Log; import com.android.ims.internal.IImsServiceFeatureCallback; import com.android.ims.rcs.uce.RcsCapabilityExchangeImplAdapter.PublishResponseCallback; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.ITelephony; import com.android.telephony.Rlog; Loading Loading @@ -450,7 +451,12 @@ public class RcsFeatureManager implements FeatureUpdates { mRcsFeatureConnection.requestPublication(capabilities, taskId); } public void requestPublication(String pidfXml, PublishResponseCallback responseCallback) public void setCapabilityExchangeEventListener(ICapabilityExchangeEventListener listener) throws RemoteException { mRcsFeatureConnection.setCapabilityExchangeEventListener(listener); } public void requestPublication(String pidfXml, IPublishResponseCallback responseCallback) throws RemoteException { mRcsFeatureConnection.requestPublication(pidfXml, responseCallback); } Loading
src/java/com/android/ims/rcs/uce/RcsCapabilityExchangeImplAdapter.javadeleted 100644 → 0 +0 −118 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 com.android.ims.rcs.uce; import android.annotation.NonNull; import android.annotation.Nullable; import android.net.Uri; import android.telephony.ims.ImsException; import java.util.List; /** * The adapter class of RcsCapabilityExchangeImplBase */ public class RcsCapabilityExchangeImplAdapter { /** Service is unknown. */ public static final int COMMAND_CODE_SERVICE_UNKNOWN = 0; /** The command failed with an unknown error. */ public static final int COMMAND_CODE_GENERIC_FAILURE = 1; /** Invalid parameter(s). */ public static final int COMMAND_CODE_INVALID_PARAM = 2; /** Fetch error. */ public static final int COMMAND_CODE_FETCH_ERROR = 3; /** Request timed out. */ public static final int COMMAND_CODE_REQUEST_TIMEOUT = 4; /** Failure due to insufficient memory available. */ public static final int COMMAND_CODE_INSUFFICIENT_MEMORY = 5; /** Network connection is lost. */ public static final int COMMAND_CODE_LOST_NETWORK_CONNECTION = 6; /** Requested feature/resource is not supported. */ public static final int COMMAND_CODE_NOT_SUPPORTED = 7; /** Contact or resource is not found. */ public static final int COMMAND_CODE_NOT_FOUND = 8; /** Service is not available. */ public static final int COMMAND_CODE_SERVICE_UNAVAILABLE = 9; /** Command resulted in no change in state, ignoring. */ public static final int COMMAND_CODE_NO_CHANGE = 10; /** * The adapter class of the interface PublishResponseCallback */ public interface PublishResponseCallback { /** * Notify the framework that the command associated with this callback has failed. */ void onCommandError(int code) throws ImsException; /** * Provide the framework with a subsequent network response update to * {@link #publishCapabilities(RcsContactUceCapability, int)}. */ void onNetworkResponse(int code, @NonNull String reason) throws ImsException; } /** * The adapter class of the interface OptionsResponseCallback */ public interface OptionsResponseCallback { /** * Notify the framework that the command associated with this callback has * failed. */ void onCommandError(int code) throws ImsException; /** * Send the response of a SIP OPTIONS capability exchange to the framework. */ void onNetworkResponse(int code, @NonNull String reason, @Nullable List<String> theirCaps) throws ImsException; } /** * The adapter class of the interface SubscribeResponseCallback */ public interface SubscribeResponseCallback { /** * Notify the framework that the command associated with this callback has failed. */ void onCommandError(int code) throws ImsException; /** * Notify the framework of the response to the SUBSCRIBE request from * {@link #subscribeForCapabilities(RcsContactUceCapability, int)}. */ void onNetworkResponse(int code, @NonNull String reason) throws ImsException; /** * Provides the framework with latest XML PIDF documents included in the * network response for the requested contacts' capabilities requested by the * Framework using {@link #requestCapabilities(List, int)}. This should be * called every time a new NOTIFY event is received with new capability * information. */ void onNotifyCapabilitiesUpdate(@NonNull List<String> pidfXmls) throws ImsException; /** * The subscription associated with a previous #requestCapabilities operation * has been terminated. This will mostly be due to the subscription expiring, * but may also happen due to an error. */ void onTerminated(String reason, String retryAfter) throws ImsException; } }
src/java/com/android/ims/rcs/uce/UceController.java +126 −26 Original line number Diff line number Diff line Loading @@ -21,25 +21,32 @@ import android.content.Context; import android.net.Uri; import android.os.HandlerThread; import android.os.Looper; import android.os.RemoteException; import android.telephony.ims.RcsContactUceCapability; import android.telephony.ims.RcsUceAdapter; import android.telephony.ims.RcsUceAdapter.CapabilitiesCallback; import android.telephony.ims.RcsUceAdapter.PublishState; import android.telephony.ims.RcsUceAdapter.StackPublishTriggerType; import android.telephony.ims.RcsUceAdapter.PublishStateCallback; import android.telephony.ims.aidl.ICapabilityExchangeEventListener; import android.telephony.ims.aidl.IOptionsRequestCallback; import android.telephony.ims.aidl.IOptionsResponseCallback; import android.telephony.ims.aidl.IRcsUceControllerCallback; import android.telephony.ims.aidl.IRcsUcePublishStateCallback; import android.util.Log; import com.android.ims.RcsFeatureManager; import com.android.ims.rcs.uce.eab.EabCapabilityResult; import com.android.ims.rcs.uce.eab.EabController; import com.android.ims.rcs.uce.eab.EabControllerImpl; import com.android.ims.rcs.uce.options.OptionsController; import com.android.ims.rcs.uce.options.OptionsControllerImpl; import com.android.ims.rcs.uce.presence.publish.PublishController; import com.android.ims.rcs.uce.presence.publish.PublishControllerImpl; import com.android.ims.rcs.uce.presence.subscribe.SubscribeController; import com.android.ims.rcs.uce.presence.subscribe.SubscribeControllerImpl; import com.android.internal.annotations.VisibleForTesting; import java.util.Arrays; import java.util.List; import java.util.Objects; /** * The UceController will manage the RCS UCE requests on a per subscription basis. When it receives Loading Loading @@ -80,14 +87,14 @@ public class UceController { */ void requestCapabilitiesByOptions(@NonNull Uri contactUri, @NonNull RcsContactUceCapability ownCapabilities, @NonNull RcsCapabilityExchangeImplAdapter.OptionsResponseCallback callback); @NonNull IOptionsResponseCallback callback); /** * The method is called when the given contacts' capabilities are expired and need to be * refreshed. */ void refreshCapabilities(@NonNull List<Uri> contactNumbers, @NonNull CapabilitiesCallback callback); @NonNull IRcsUceControllerCallback callback) throws RemoteException; /** * The method is called when the EabController and the PublishController want to receive Loading @@ -109,6 +116,9 @@ public class UceController { UceRequestTaskManager createTaskManager(Context context, int subId, Looper looper); } private RequestTaskManagerFactory mTaskManagerFactory = (context, subId, looper) -> new UceRequestTaskManager(context, subId, looper); /** * Used to inject Controller instances for testing. */ Loading Loading @@ -138,31 +148,61 @@ public class UceController { UceControllerCallback c, Looper looper); } private ControllerFactory mControllerFactory = new ControllerFactory() { @Override public EabController createEabController(Context context, int subId, UceControllerCallback c, Looper looper) { return new EabControllerImpl(context, subId, c, looper); } @Override public PublishController createPublishController(Context context, int subId, Looper looper) { return new PublishControllerImpl(context, subId, looper); } @Override public SubscribeController createSubscribeController(Context context, int subId, UceControllerCallback c, Looper looper) { return new SubscribeControllerImpl(context, subId, c, looper); } @Override public OptionsController createOptionsController(Context context, int subId, UceControllerCallback c, Looper looper) { return new OptionsControllerImpl(context, subId, c, looper); } }; private final int mSubId; private final Context mContext; private volatile boolean mIsRcsConnected; private volatile boolean mIsDestroyedFlag; private Looper mLooper; private UceRequestTaskManager mTaskManager; private final RequestTaskManagerFactory mTaskManagerFactory; private EabController mEabController; private PublishController mPublishController; private SubscribeController mSubscribeController; private OptionsController mOptionsController; private final ControllerFactory mControllerFactory; private UceRequestTaskManager mTaskManager; public UceController(Context context, int subId, ControllerFactory controllerFactory, RequestTaskManagerFactory taskManagerFactory) { public UceController(Context context, int subId) { mSubId = subId; mContext = context; logi("create"); initLooper(); initRequestTaskManager(); initControllers(); } @VisibleForTesting public UceController(Context context, int subId, ControllerFactory controllerFactory, RequestTaskManagerFactory taskManagerFactory) { mSubId = subId; mContext = context; mControllerFactory = controllerFactory; mTaskManagerFactory = taskManagerFactory; initLooper(); initRequestTaskManager(); initControllers(); Loading Loading @@ -200,6 +240,12 @@ public class UceController { mPublishController.onRcsConnected(manager); mSubscribeController.onRcsConnected(manager); mOptionsController.onRcsConnected(manager); try { manager.setCapabilityExchangeEventListener(mCapabilityEventListener); } catch (RemoteException e) { logw("Set capability event listener error: " + e.getMessage()); } } /** Loading Loading @@ -230,7 +276,10 @@ public class UceController { mLooper.quit(); } // The implementation of the interface UceControllerCallback. /* * The implementation of the interface UceControllerCallback. These methods are called by other * controllers. */ private UceControllerCallback mCtrlCallback = new UceControllerCallback() { @Override public EabCapabilityResult getCapabilitiesFromCache(List<Uri> uris) { Loading @@ -253,14 +302,15 @@ public class UceController { } @Override public void requestCapabilitiesByOptions(Uri uri, RcsContactUceCapability ownCapabilities, RcsCapabilityExchangeImplAdapter.OptionsResponseCallback callback) { public void requestCapabilitiesByOptions(@NonNull Uri uri, @NonNull RcsContactUceCapability ownCapabilities, @NonNull IOptionsResponseCallback callback) { mOptionsController.sendCapabilitiesRequest(uri, ownCapabilities, callback); } @Override public void refreshCapabilities(@NonNull List<Uri> contactNumbers, @NonNull CapabilitiesCallback callback) { @NonNull IRcsUceControllerCallback callback) throws RemoteException{ logd("refreshCapabilities: " + contactNumbers.size()); UceController.this.requestCapabilities(contactNumbers, callback); } Loading @@ -283,12 +333,44 @@ public class UceController { mCtrlCallback = callback; } /* * Setup the listener to listen to the requests and updates from ImsService. */ private ICapabilityExchangeEventListener mCapabilityEventListener = new ICapabilityExchangeEventListener.Stub() { @Override public void onRequestPublishCapabilities( @StackPublishTriggerType int publishTriggerType) { onRequestPublishCapabilitiesFromService(publishTriggerType); } @Override public void onUnpublish() { UceController.this.onUnpublish(); } @Override public void onRemoteCapabilityRequest(Uri contactUri, List<String> remoteCapabilities, IOptionsRequestCallback cb) { retrieveOptionsCapabilitiesForRemote(contactUri, remoteCapabilities, cb); } }; /** * Request to get the contacts' capabilities. This method will retrieve the capabilities from * the cache If the capabilities are out of date, it will trigger another request to get the * latest contact's capabilities from the carrier network. */ public void requestCapabilities(@NonNull List<Uri> uriList, @NonNull CapabilitiesCallback c) { public void requestCapabilities(@NonNull List<Uri> uriList, @NonNull IRcsUceControllerCallback c) throws RemoteException { if (uriList == null || c == null) { logw("requestCapabilities: parameter is empty"); if (c != null) { c.onError(RcsUceAdapter.ERROR_GENERIC_FAILURE); } return; } if (isUnavailable()) { logw("requestCapabilities: controller is unavailable"); c.onError(RcsUceAdapter.ERROR_GENERIC_FAILURE); Loading @@ -296,7 +378,7 @@ public class UceController { } // Trigger the capabilities request task logd("requestCapabilities"); logd("requestCapabilities: " + uriList.size()); mTaskManager.triggerCapabilityRequestTask(mCtrlCallback, uriList, c); } Loading @@ -305,7 +387,16 @@ public class UceController { * the capability in the availability cache is expired then it will retrieve the capability * from the carrier network. */ public void requestAvailability(@NonNull Uri uri, @NonNull CapabilitiesCallback c) { public void requestAvailability(@NonNull Uri uri, @NonNull IRcsUceControllerCallback c) throws RemoteException{ if (uri == null || c == null) { logw("requestCapabilities: parameter is empty"); if (c != null) { c.onError(RcsUceAdapter.ERROR_GENERIC_FAILURE); } return; } if (isUnavailable()) { logw("requestAvailability: controller is unavailable"); c.onError(RcsUceAdapter.ERROR_GENERIC_FAILURE); Loading @@ -320,9 +411,9 @@ public class UceController { /** * Publish the device's capabilities. This request is triggered from the ImsService. */ public void onRequestPublishCapabilitiesFromService() { logd("onRequestPublishCapabilitiesFromService"); mPublishController.requestPublishCapabilitiesFromService(); public void onRequestPublishCapabilitiesFromService(@StackPublishTriggerType int triggerType) { logd("onRequestPublishCapabilitiesFromService: " + triggerType); mPublishController.requestPublishCapabilitiesFromService(triggerType); } /** Loading @@ -339,8 +430,7 @@ public class UceController { * capabilities to the remote side. */ public void retrieveOptionsCapabilitiesForRemote(@NonNull Uri contactUri, @NonNull List<String> remoteCapabilities, @NonNull CapabilityExchangeListenerAdapter.OptionsRequestCallback c) { @NonNull List<String> remoteCapabilities, @NonNull IOptionsRequestCallback c) { logd("retrieveOptionsCapabilitiesForRemote"); mOptionsController.retrieveCapabilitiesForRemote(contactUri, remoteCapabilities, c); } Loading @@ -366,11 +456,21 @@ public class UceController { return mPublishController.getUcePublishState(); } @VisibleForTesting public void setRequestTaskManagerFactory(RequestTaskManagerFactory factory) { mTaskManagerFactory = factory; } @VisibleForTesting public void setControllerFactory(ControllerFactory factory) { mControllerFactory = factory; } public int getSubId() { return mSubId; } private boolean isUnavailable() { public boolean isUnavailable() { if (!mIsRcsConnected || mIsDestroyedFlag) { return true; } Loading
src/java/com/android/ims/rcs/uce/UceRequestTaskManager.java +26 −7 Original line number Diff line number Diff line Loading @@ -16,8 +16,10 @@ package com.android.ims.rcs.uce; import android.content.Context; import android.net.Uri; import android.telephony.ims.RcsUceAdapter; import android.os.Looper; import android.telephony.ims.aidl.IRcsUceControllerCallback; import com.android.ims.rcs.uce.UceController.UceControllerCallback; Loading @@ -26,20 +28,37 @@ import java.util.List; /** * The interface of managing the capability request and the availability request. */ public interface UceRequestTaskManager { public class UceRequestTaskManager { private final Context mContext; private final int mSubId; private final Looper mLooper; public UceRequestTaskManager(Context context, int subId, Looper looper) { mContext = context; mSubId = subId; mLooper = looper; } /** * Trigger the capability request task. */ void triggerCapabilityRequestTask(UceControllerCallback controller, List<Uri> uriList, RcsUceAdapter.CapabilitiesCallback callback); public void triggerCapabilityRequestTask(UceControllerCallback controller, List<Uri> uriList, IRcsUceControllerCallback callback) { // TODO: Implement this method } /** * Trigger the availability request task. */ void triggerAvailabilityRequestTask(UceControllerCallback controller, Uri uri, RcsUceAdapter.CapabilitiesCallback callback); public void triggerAvailabilityRequestTask(UceControllerCallback controller, Uri uri, IRcsUceControllerCallback callback) { // TODO: Implement this method } /** * Notify the task manager to destroy. */ void onDestroy(); public void onDestroy() { // TODO: Implement this method } }