diff options
Diffstat (limited to 'src/java/com/android/ims/rcs/uce')
8 files changed, 443 insertions, 14 deletions
diff --git a/src/java/com/android/ims/rcs/uce/UceStatsWriter.java b/src/java/com/android/ims/rcs/uce/UceStatsWriter.java new file mode 100644 index 00000000..1db9040c --- /dev/null +++ b/src/java/com/android/ims/rcs/uce/UceStatsWriter.java @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2021 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.IntDef; +import android.telephony.ims.stub.ImsRegistrationImplBase; +import android.telephony.ims.stub.RcsCapabilityExchangeImplBase; +import android.telephony.ims.RcsContactPresenceTuple; +import android.telephony.ims.RcsContactUceCapability; +import com.android.internal.annotations.VisibleForTesting; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +/** + * The UceStatsWriter should be a singleton class for storing atoms in RcsStats. + * ims-common provides an interface for setting atoms to telephony-common. + **/ +public class UceStatsWriter { + private static UceStatsWriter sInstance = null; + private UceStatsCallback mCallBack; + + /** + * @hide + */ + // Defines which UCE event occurred. + @IntDef(value = { + PUBLISH_EVENT, + SUBSCRIBE_EVENT, + INCOMING_OPTION_EVENT, + OUTGOING_OPTION_EVENT + }) + @Retention(RetentionPolicy.SOURCE) + public @interface UceEventType {} + /** + * UCE events related to Publish Method. + */ + public static final int PUBLISH_EVENT = 0; + /** + * UCE events related to Subscribe Method. + */ + public static final int SUBSCRIBE_EVENT = 1; + /** + * UCE events related to incoming Options Method. + */ + public static final int INCOMING_OPTION_EVENT = 2; + /** + * UCE events related to outgoing Options Method. + */ + public static final int OUTGOING_OPTION_EVENT = 3; + + /** + * The callback interface is called by the Metrics data creator to receive information from + * others controllers. + */ + public interface UceStatsCallback { + /** + * Notify the callback listener that the feature tag associated with + * IMS registration of this device have changed. + */ + public void onImsRegistrationFeatureTagStats(int subId, List<String> featureTagList, + int registrationTech); + + /** + * Notify that the active IMS registration to the carrier network has been terminated. + */ + public void onStoreCompleteImsRegistrationFeatureTagStats(int subId); + + /** + * Notify the callback listener that the PIDF ServiceDescriptions associated with + * the UCE presence of this device have changed. + */ + void onImsRegistrationServiceDescStats(int subId, List<String> serviceIdList, + List<String> serviceIdVersionList, int registrationTech); + + /** + * Notify the callback listener that a subscribe response received. + */ + void onSubscribeResponse(int subId, long taskId, int networkResponse); + + /** + * Notify the callback listener that a UCE Network Event has occurred. + */ + void onUceEvent(int subId, int type, boolean successful, int commandCode, + int networkResponse); + + /** + * Notify the callback listener that a subscribe has ended. + */ + void onSubscribeTerminated(int subId, long taskId, String reason); + + /** + * Notify that the Presence Notify Event has changed. + */ + void onPresenceNotifyEvent(int subId, long taskId, + List<RcsContactUceCapability> updatedCapList); + + /** + * Notify that the active UCE PUBLISH to the carrier network has been terminated. + */ + void onStoreCompleteImsRegistrationServiceDescStats(int subId); + } + + /** + * create an instance of UceStatsWriter + */ + public static UceStatsWriter init(UceStatsCallback callback) { + synchronized (UceStatsWriter.class) { + if (sInstance == null) { + sInstance = new UceStatsWriter(callback); + } + return sInstance; + } + } + + /** + * get the current instance of UceStatsWriter + */ + public static UceStatsWriter getInstance() { + synchronized (UceStatsWriter.class) { + return sInstance; + } + } + + /** + * Stats about each Feature tag that was included in IMS registration received from + * the network during register. + * @param subId The subId associated with the event. + * @param featureTagList Ims Feature tag list. + * @param registrationTech The registration tech associated with the feature tag. + */ + public void setImsRegistrationFeatureTagStats(int subId, List<String> featureTagList, + @ImsRegistrationImplBase.ImsRegistrationTech int registrationTech) { + if (mCallBack == null) { + return; + } + mCallBack.onImsRegistrationFeatureTagStats(subId, featureTagList, registrationTech); + } + + /** + * Update time of stats for each stored feature tag. + * @param subId The subId associated with the event. + */ + public void setStoreCompleteImsRegistrationFeatureTagStats(int subId) { + if (mCallBack == null) { + return; + } + mCallBack.onStoreCompleteImsRegistrationFeatureTagStats(subId); + } + + /** + * Stats about each ServiceDescription that was included in the PIDF XML sent to + * the network during publish + * @param subId The subId associated with the event. + * @param tupleList Tuple information set in PIDF. + * @param registrationTech The registration tech associated with the feature tag. + */ + public void setImsRegistrationServiceDescStats(int subId, + List<RcsContactPresenceTuple> tupleList, + @ImsRegistrationImplBase.ImsRegistrationTech int registrationTech) { + if (mCallBack == null) { + return; + } + ArrayList<String> svcId = new ArrayList<>(); + ArrayList<String> svcVersion = new ArrayList<>(); + + for (RcsContactPresenceTuple tuple : tupleList) { + svcId.add(tuple.getServiceId()); + svcVersion.add(tuple.getServiceVersion()); + } + mCallBack.onImsRegistrationServiceDescStats(subId, svcId, svcVersion, registrationTech); + } + + /** + * Stats related to UCE queries to the network + * @param subId The subId associated with the event. + * @param taskId The taskId associate with the event. + * @param networkResponse The network response code for the Uce event + */ + public void setSubscribeResponse(int subId, long taskId, int networkResponse) { + if (mCallBack != null) { + mCallBack.onSubscribeResponse(subId, taskId, networkResponse); + } + } + + /** + * Stats related to UCE queries to the network + * @param subId The subId associated with the event. + * @param type Used to identify the message type. + * @param successful Whether the UCE event is successfully finished. + * @param commandCode The command error code for the Uce event + * @param networkResponse The network response code for the Uce event + */ + public void setUceEvent(int subId, @UceEventType int type, boolean successful, + @RcsCapabilityExchangeImplBase.CommandCode int commandCode, int networkResponse) { + if (mCallBack != null) { + mCallBack.onUceEvent(subId, type, successful, commandCode, networkResponse); + } + } + + /** + * The result of processing received notify messages. + * @param subId The subId associated with the event. + * @param taskId The taskId associate with the event. + * @param updatedCapList Capability information of the user contained in Presence Notify. + */ + public void setPresenceNotifyEvent(int subId, long taskId, + List<RcsContactUceCapability> updatedCapList) { + if (mCallBack == null || updatedCapList == null || updatedCapList.isEmpty()) { + return; + } + mCallBack.onPresenceNotifyEvent(subId, taskId, updatedCapList); + } + + /** + * Indicates that the subscription request has become a terminated state. + * @param subId The subId associated with the event. + * @param taskId The taskId associate with the event. + * @param reason The terminated reason associated with the subscription state. + */ + public void setSubscribeTerminated(int subId, long taskId, String reason) { + if (mCallBack != null) { + mCallBack.onSubscribeTerminated(subId, taskId, reason); + } + } + + /** + * indicates that the device has removed an existing PUBLISH from the carrier's network + * containing the device's RCS capabilities state. + * The registered time of publication must be set in ImsRegistrationServiceDescStats, + * which is the life time of publication, so it can be set only when publication is over. + * @param subId The subId associated with the event. + */ + public void setUnPublish(int subId) { + if (mCallBack != null) { + mCallBack.onStoreCompleteImsRegistrationServiceDescStats(subId); + } + } + + @VisibleForTesting + protected UceStatsWriter(UceStatsCallback callback) { + mCallBack = callback; + } +} diff --git a/src/java/com/android/ims/rcs/uce/presence/publish/DeviceCapabilityListener.java b/src/java/com/android/ims/rcs/uce/presence/publish/DeviceCapabilityListener.java index e881ae0c..872d35dc 100644 --- a/src/java/com/android/ims/rcs/uce/presence/publish/DeviceCapabilityListener.java +++ b/src/java/com/android/ims/rcs/uce/presence/publish/DeviceCapabilityListener.java @@ -46,6 +46,7 @@ import android.util.IndentingPrintWriter; import android.util.LocalLog; import android.util.Log; +import com.android.ims.rcs.uce.UceStatsWriter; import com.android.ims.rcs.uce.presence.publish.PublishController.PublishControllerCallback; import com.android.ims.rcs.uce.presence.publish.PublishController.PublishTriggerType; import com.android.ims.rcs.uce.util.UceUtils; @@ -53,7 +54,12 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.util.HandlerExecutor; import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; import java.util.Objects; +import java.util.Set; /** * Listen to the device changes and notify the PublishController to publish the device's @@ -65,6 +71,8 @@ public class DeviceCapabilityListener { private static final long REGISTER_IMS_CHANGED_DELAY = 15000L; // 15 seconds + private final UceStatsWriter mUceStatsWriter; + /** * Used to inject ImsMmTelManager instances for testing. */ @@ -180,7 +188,7 @@ public class DeviceCapabilityListener { private final Object mLock = new Object(); public DeviceCapabilityListener(Context context, int subId, DeviceCapabilityInfo info, - PublishControllerCallback callback) { + PublishControllerCallback callback, UceStatsWriter uceStatsWriter) { mSubId = subId; logi("create"); @@ -188,6 +196,7 @@ public class DeviceCapabilityListener { mCallback = callback; mCapabilityInfo = info; mInitialized = false; + mUceStatsWriter = uceStatsWriter; mHandlerThread = new HandlerThread("DeviceCapListenerThread"); mHandlerThread.start(); @@ -447,6 +456,12 @@ public class DeviceCapabilityListener { synchronized (mLock) { logi("onRcsRegistered: " + attributes); if (!mIsImsCallbackRegistered) return; + + List<String> featureTagList = new ArrayList<>(attributes.getFeatureTags()); + int registrationTech = attributes.getRegistrationTechnology(); + + mUceStatsWriter.setImsRegistrationFeatureTagStats( + mSubId, featureTagList, registrationTech); handleImsRcsRegistered(attributes); } } @@ -456,6 +471,7 @@ public class DeviceCapabilityListener { synchronized (mLock) { logi("onRcsUnregistered: " + info); if (!mIsImsCallbackRegistered) return; + mUceStatsWriter.setStoreCompleteImsRegistrationFeatureTagStats(mSubId); handleImsRcsUnregistered(); } } diff --git a/src/java/com/android/ims/rcs/uce/presence/publish/PublishControllerImpl.java b/src/java/com/android/ims/rcs/uce/presence/publish/PublishControllerImpl.java index e2340ff5..0ff48856 100644 --- a/src/java/com/android/ims/rcs/uce/presence/publish/PublishControllerImpl.java +++ b/src/java/com/android/ims/rcs/uce/presence/publish/PublishControllerImpl.java @@ -44,6 +44,7 @@ import com.android.ims.rcs.uce.UceController; import com.android.ims.rcs.uce.UceController.UceControllerCallback; import com.android.ims.rcs.uce.UceDeviceState; import com.android.ims.rcs.uce.UceDeviceState.DeviceStateResult; +import com.android.ims.rcs.uce.UceStatsWriter; import com.android.ims.rcs.uce.util.UceUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.SomeArgs; @@ -79,7 +80,8 @@ public class PublishControllerImpl implements PublishController { @VisibleForTesting public interface DeviceCapListenerFactory { DeviceCapabilityListener createDeviceCapListener(Context context, int subId, - DeviceCapabilityInfo capInfo, PublishControllerCallback callback); + DeviceCapabilityInfo capInfo, PublishControllerCallback callback, + UceStatsWriter uceStatsWriter); } private final int mSubId; @@ -90,6 +92,7 @@ public class PublishControllerImpl implements PublishController { private volatile boolean mReceivePublishFromService; private volatile RcsFeatureManager mRcsFeatureManager; private final UceControllerCallback mUceCtrlCallback; + private final UceStatsWriter mUceStatsWriter; // The capability type that the device is using. private @RcsImsCapabilityFlag int mCapabilityType; @@ -115,8 +118,9 @@ public class PublishControllerImpl implements PublishController { // The listener to listen to the device's capabilities changed. private DeviceCapabilityListener mDeviceCapListener; - private DeviceCapListenerFactory mDeviceCapListenerFactory = (context, subId, capInfo, callback) - -> new DeviceCapabilityListener(context, subId, capInfo, callback); + private DeviceCapListenerFactory mDeviceCapListenerFactory = (context, subId, capInfo, callback, + uceStatsWriter) + -> new DeviceCapabilityListener(context, subId, capInfo, callback, uceStatsWriter); // Listen to the RCS availability status changed. private final IImsCapabilityCallback mRcsCapabilitiesCallback = @@ -141,6 +145,7 @@ public class PublishControllerImpl implements PublishController { mSubId = subId; mContext = context; mUceCtrlCallback = callback; + mUceStatsWriter = UceStatsWriter.getInstance(); logi("create"); initPublishController(looper); } @@ -148,12 +153,13 @@ public class PublishControllerImpl implements PublishController { @VisibleForTesting public PublishControllerImpl(Context context, int subId, UceControllerCallback c, Looper looper, DeviceCapListenerFactory deviceCapFactory, - PublishProcessorFactory processorFactory) { + PublishProcessorFactory processorFactory, UceStatsWriter instance) { mSubId = subId; mContext = context; mUceCtrlCallback = c; mDeviceCapListenerFactory = deviceCapFactory; mPublishProcessorFactory = processorFactory; + mUceStatsWriter = instance; initPublishController(looper); } @@ -200,7 +206,7 @@ public class PublishControllerImpl implements PublishController { private void initDeviceCapabilitiesListener() { mDeviceCapListener = mDeviceCapListenerFactory.createDeviceCapListener(mContext, mSubId, - mDeviceCapabilityInfo, mPublishControllerCallback); + mDeviceCapabilityInfo, mPublishControllerCallback, mUceStatsWriter); } @Override @@ -330,8 +336,7 @@ public class PublishControllerImpl implements PublishController { public void onUnpublish() { logd("onUnpublish"); if (mIsDestroyedFlag) return; - mPublishHandler.sendPublishStateChangedMessage(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED, - Instant.now(), null /*pidfXml*/); + mPublishHandler.sendUnpublishedMessage(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED); } @Override @@ -416,6 +421,7 @@ public class PublishControllerImpl implements PublishController { private static final int MSG_REQUEST_NETWORK_RESPONSE = 10; private static final int MSG_REQUEST_CANCELED = 11; private static final int MSG_RESET_DEVICE_STATE = 12; + private static final int MSG_UNPUBLISHED = 13; private final WeakReference<PublishControllerImpl> mPublishControllerRef; @@ -496,6 +502,14 @@ public class PublishControllerImpl implements PublishController { publishCtrl.handleResetDeviceStateMessage(); break; + case MSG_UNPUBLISHED: { + SomeArgs args = (SomeArgs) message.obj; + int newPublishState = (Integer) args.arg1; + Instant updatedTimestamp = (Instant) args.arg2; + args.recycle(); + publishCtrl.handleUnpublishedMessage(newPublishState, updatedTimestamp); + break; + } default: publishCtrl.logd("invalid message: " + message.what); break; @@ -584,6 +598,22 @@ public class PublishControllerImpl implements PublishController { } /** + * Send the message to notify the publish state is changed. + */ + public void sendUnpublishedMessage(@PublishState int publishState) { + PublishControllerImpl publishCtrl = mPublishControllerRef.get(); + if (publishCtrl == null) return; + if (publishCtrl.mIsDestroyedFlag) return; + + SomeArgs args = SomeArgs.obtain(); + args.arg1 = publishState; + args.arg2 = Instant.now(); + Message message = obtainMessage(); + message.what = MSG_UNPUBLISHED; + message.obj = args; + sendMessage(message); + } + /** * Send the message to notify the new added callback of the latest publish state. */ public void sendNotifyCurrentPublishStateMessage( @@ -703,6 +733,7 @@ public class PublishControllerImpl implements PublishController { EVENT_DESCRIPTION.put(MSG_REQUEST_NETWORK_RESPONSE, "REQUEST_NETWORK_RESPONSE"); EVENT_DESCRIPTION.put(MSG_REQUEST_CANCELED, "REQUEST_CANCELED"); EVENT_DESCRIPTION.put(MSG_RESET_DEVICE_STATE, "RESET_DEVICE_STATE"); + EVENT_DESCRIPTION.put(MSG_UNPUBLISHED, "MSG_UNPUBLISHED"); } } @@ -909,6 +940,9 @@ public class PublishControllerImpl implements PublishController { if (mPublishState == newPublishState) return; mPublishState = newPublishState; } + if (newPublishState == RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED) { + mUceStatsWriter.setUnPublish(mSubId); + } // Trigger the publish state changed in handler thread since it may take time. logd("Notify publish state changed: " + mPublishState); @@ -988,6 +1022,13 @@ public class PublishControllerImpl implements PublishController { mUceCtrlCallback.resetDeviceState(); } + private void handleUnpublishedMessage(@PublishState int newPublishState, + Instant updatedTimestamp) { + if (mIsDestroyedFlag) return; + mPublishProcessor.resetState(); + handlePublishStateChangedMessage(newPublishState, updatedTimestamp, null); + } + @VisibleForTesting public void setCapabilityType(int type) { mCapabilityType = type; diff --git a/src/java/com/android/ims/rcs/uce/presence/publish/PublishProcessor.java b/src/java/com/android/ims/rcs/uce/presence/publish/PublishProcessor.java index 68aeaa8f..01aa22b9 100644 --- a/src/java/com/android/ims/rcs/uce/presence/publish/PublishProcessor.java +++ b/src/java/com/android/ims/rcs/uce/presence/publish/PublishProcessor.java @@ -22,6 +22,8 @@ import android.annotation.NonNull; import android.content.Context; import android.os.RemoteException; import android.telephony.ims.RcsContactUceCapability; +import android.telephony.ims.stub.ImsRegistrationImplBase; +import android.telephony.ims.stub.RcsCapabilityExchangeImplBase; import android.text.TextUtils; import android.util.IndentingPrintWriter; import android.util.LocalLog; @@ -31,6 +33,7 @@ import com.android.ims.RcsFeatureManager; import com.android.ims.rcs.uce.presence.pidfparser.PidfParser; import com.android.ims.rcs.uce.presence.publish.PublishController.PublishControllerCallback; import com.android.ims.rcs.uce.presence.publish.PublishController.PublishTriggerType; +import com.android.ims.rcs.uce.UceStatsWriter; import com.android.ims.rcs.uce.util.UceUtils; import com.android.internal.annotations.VisibleForTesting; @@ -53,6 +56,8 @@ public class PublishProcessor { private volatile boolean mIsDestroyed; private volatile RcsFeatureManager mRcsFeatureManager; + private final UceStatsWriter mUceStatsWriter; + // Manage the state of the publish processor. private PublishProcessorState mProcessorState; @@ -74,6 +79,18 @@ public class PublishProcessor { mDeviceCapabilities = capabilityInfo; mPublishCtrlCallback = publishCtrlCallback; mProcessorState = new PublishProcessorState(subId); + mUceStatsWriter = UceStatsWriter.getInstance(); + } + + @VisibleForTesting + public PublishProcessor(Context context, int subId, DeviceCapabilityInfo capabilityInfo, + PublishControllerCallback publishCtrlCallback, UceStatsWriter instance) { + mSubId = subId; + mContext = context; + mDeviceCapabilities = capabilityInfo; + mPublishCtrlCallback = publishCtrlCallback; + mProcessorState = new PublishProcessorState(subId); + mUceStatsWriter = instance; } /** @@ -158,6 +175,13 @@ public class PublishProcessor { return false; } + featureManager.getImsRegistrationTech((tech) -> { + int registrationTech = (tech == null) + ? ImsRegistrationImplBase.REGISTRATION_TECH_NONE : tech; + mUceStatsWriter.setImsRegistrationServiceDescStats(mSubId, + deviceCapability.getCapabilityTuples(), registrationTech); + }); + // Publish to the Presence server. return publishCapabilities(featureManager, pidfXml); } @@ -244,6 +268,13 @@ public class PublishProcessor { mLocalLog.log("Receive command error code=" + requestResponse.getCmdErrorCode()); logd("onCommandError: " + requestResponse.toString()); + int cmdError = requestResponse.getCmdErrorCode().orElse(0); + boolean successful = false; + if (cmdError == RcsCapabilityExchangeImplBase.COMMAND_CODE_NO_CHANGE) { + successful = true; + } + mUceStatsWriter.setUceEvent(mSubId, UceStatsWriter.PUBLISH_EVENT, successful, cmdError, 0); + if (requestResponse.needRetry() && !mProcessorState.isReachMaximumRetries()) { handleRequestRespWithRetry(requestResponse); } else { @@ -267,6 +298,10 @@ public class PublishProcessor { mLocalLog.log("Receive network response code=" + requestResponse.getNetworkRespSipCode()); logd("onNetworkResponse: " + requestResponse.toString()); + int responseCode = requestResponse.getNetworkRespSipCode().orElse(0); + mUceStatsWriter.setUceEvent(mSubId, UceStatsWriter.PUBLISH_EVENT, true, 0, + responseCode); + if (requestResponse.needRetry() && !mProcessorState.isReachMaximumRetries()) { handleRequestRespWithRetry(requestResponse); } else { @@ -445,6 +480,12 @@ public class PublishProcessor { return mProcessorState.isPublishingNow(); } + /** + * Reset the retry count and time related publish. + */ + public void resetState() { + mProcessorState.resetState(); + } @VisibleForTesting public void setProcessorState(PublishProcessorState processorState) { mProcessorState = processorState; diff --git a/src/java/com/android/ims/rcs/uce/presence/publish/PublishProcessorState.java b/src/java/com/android/ims/rcs/uce/presence/publish/PublishProcessorState.java index 40d901f6..0e9adfad 100644 --- a/src/java/com/android/ims/rcs/uce/presence/publish/PublishProcessorState.java +++ b/src/java/com/android/ims/rcs/uce/presence/publish/PublishProcessorState.java @@ -348,6 +348,16 @@ public class PublishProcessorState { } } + /** + * Reset the retry count and related time when the publication status has + * changed to not_published. + */ + public void resetState() { + synchronized (mLock) { + mPublishThrottle.resetState(); + } + } + /* * Check if it has reached the maximum retry count. */ diff --git a/src/java/com/android/ims/rcs/uce/request/OptionsRequestCoordinator.java b/src/java/com/android/ims/rcs/uce/request/OptionsRequestCoordinator.java index a150dd6d..a2660931 100644 --- a/src/java/com/android/ims/rcs/uce/request/OptionsRequestCoordinator.java +++ b/src/java/com/android/ims/rcs/uce/request/OptionsRequestCoordinator.java @@ -24,6 +24,7 @@ import android.telephony.ims.RcsUceAdapter; import android.telephony.ims.aidl.IRcsUceControllerCallback; import com.android.ims.rcs.uce.request.UceRequestManager.RequestManagerCallback; +import com.android.ims.rcs.uce.UceStatsWriter; import com.android.internal.annotations.VisibleForTesting; import java.util.Collection; @@ -44,7 +45,14 @@ public class OptionsRequestCoordinator extends UceRequestCoordinator { public Builder(int subId, Collection<UceRequest> requests, RequestManagerCallback callback) { - mRequestCoordinator = new OptionsRequestCoordinator(subId, requests, callback); + mRequestCoordinator = new OptionsRequestCoordinator(subId, requests, callback, + UceStatsWriter.getInstance()); + } + @VisibleForTesting + public Builder(int subId, Collection<UceRequest> requests, + RequestManagerCallback callback, UceStatsWriter instance) { + mRequestCoordinator = new OptionsRequestCoordinator(subId, requests, callback, + instance); } public Builder setCapabilitiesCallback(IRcsUceControllerCallback callback) { @@ -105,9 +113,12 @@ public class OptionsRequestCoordinator extends UceRequestCoordinator { // The callback to notify the result of the capabilities request. private IRcsUceControllerCallback mCapabilitiesCallback; + private final UceStatsWriter mUceStatsWriter; + private OptionsRequestCoordinator(int subId, Collection<UceRequest> requests, - RequestManagerCallback requestMgrCallback) { + RequestManagerCallback requestMgrCallback, UceStatsWriter instance) { super(subId, requests, requestMgrCallback); + mUceStatsWriter = instance; logd("OptionsRequestCoordinator: created"); } @@ -189,6 +200,11 @@ public class OptionsRequestCoordinator extends UceRequestCoordinator { // Finish this request. request.onFinish(); + int commandErrorCode = response.getCommandError().orElse(0); + mUceStatsWriter.setUceEvent(mSubId, UceStatsWriter.OUTGOING_OPTION_EVENT, + false, commandErrorCode, 0); + + // Remove this request from the activated collection and notify RequestManager. Long taskId = request.getTaskId(); RequestResult requestResult = sCommandErrorCreator.createRequestResult(taskId, response); @@ -203,6 +219,11 @@ public class OptionsRequestCoordinator extends UceRequestCoordinator { CapabilityRequestResponse response = request.getRequestResponse(); logd("handleNetworkResponse: " + response.toString()); + int responseCode = response.getNetworkRespSipCode().orElse(0); + mUceStatsWriter.setUceEvent(mSubId, UceStatsWriter.OUTGOING_OPTION_EVENT, true, + 0, responseCode); + + List<RcsContactUceCapability> updatedCapList = response.getUpdatedContactCapability(); if (!updatedCapList.isEmpty()) { // Save the capabilities and trigger the capabilities callback diff --git a/src/java/com/android/ims/rcs/uce/request/RemoteOptionsCoordinator.java b/src/java/com/android/ims/rcs/uce/request/RemoteOptionsCoordinator.java index c8aa3f77..5a3e33bb 100644 --- a/src/java/com/android/ims/rcs/uce/request/RemoteOptionsCoordinator.java +++ b/src/java/com/android/ims/rcs/uce/request/RemoteOptionsCoordinator.java @@ -25,6 +25,7 @@ import android.telephony.ims.aidl.IOptionsRequestCallback; import com.android.ims.rcs.uce.request.RemoteOptionsRequest.RemoteOptResponse; import com.android.ims.rcs.uce.request.UceRequestManager.RequestManagerCallback; +import com.android.ims.rcs.uce.UceStatsWriter; import com.android.internal.annotations.VisibleForTesting; import java.util.Collection; @@ -41,7 +42,13 @@ public class RemoteOptionsCoordinator extends UceRequestCoordinator { RemoteOptionsCoordinator mRemoteOptionsCoordinator; public Builder(int subId, Collection<UceRequest> requests, RequestManagerCallback c) { - mRemoteOptionsCoordinator = new RemoteOptionsCoordinator(subId, requests, c); + mRemoteOptionsCoordinator = new RemoteOptionsCoordinator(subId, requests, c, + UceStatsWriter.getInstance()); + } + @VisibleForTesting + public Builder(int subId, Collection<UceRequest> requests, RequestManagerCallback c, + UceStatsWriter instance) { + mRemoteOptionsCoordinator = new RemoteOptionsCoordinator(subId, requests, c, instance); } public Builder setOptionsRequestCallback(IOptionsRequestCallback callback) { @@ -78,9 +85,12 @@ public class RemoteOptionsCoordinator extends UceRequestCoordinator { // The callback to notify the result of the remote options request. private IOptionsRequestCallback mOptionsReqCallback; + private final UceStatsWriter mUceStatsWriter; + private RemoteOptionsCoordinator(int subId, Collection<UceRequest> requests, - RequestManagerCallback requestMgrCallback) { + RequestManagerCallback requestMgrCallback, UceStatsWriter instance) { super(subId, requests, requestMgrCallback); + mUceStatsWriter = instance; logd("RemoteOptionsCoordinator: created"); } @@ -144,6 +154,9 @@ public class RemoteOptionsCoordinator extends UceRequestCoordinator { boolean isRemoteNumberBlocked) { try { logd("triggerOptionsReqCallback: start"); + mUceStatsWriter.setUceEvent(mSubId, UceStatsWriter.INCOMING_OPTION_EVENT, true, 0, + 200); + mOptionsReqCallback.respondToCapabilityRequest(deviceCaps, isRemoteNumberBlocked); } catch (RemoteException e) { logw("triggerOptionsReqCallback exception: " + e); @@ -155,6 +168,9 @@ public class RemoteOptionsCoordinator extends UceRequestCoordinator { private void triggerOptionsReqWithErrorCallback(int errorCode, String reason) { try { logd("triggerOptionsReqWithErrorCallback: start"); + mUceStatsWriter.setUceEvent(mSubId, UceStatsWriter.INCOMING_OPTION_EVENT, true, 0, + errorCode); + mOptionsReqCallback.respondToCapabilityRequestWithError(errorCode, reason); } catch (RemoteException e) { logw("triggerOptionsReqWithErrorCallback exception: " + e); diff --git a/src/java/com/android/ims/rcs/uce/request/SubscribeRequestCoordinator.java b/src/java/com/android/ims/rcs/uce/request/SubscribeRequestCoordinator.java index b3cc781b..f44686ac 100644 --- a/src/java/com/android/ims/rcs/uce/request/SubscribeRequestCoordinator.java +++ b/src/java/com/android/ims/rcs/uce/request/SubscribeRequestCoordinator.java @@ -29,6 +29,7 @@ import com.android.ims.rcs.uce.eab.EabCapabilityResult; import com.android.ims.rcs.uce.presence.pidfparser.PidfParserUtils; import com.android.ims.rcs.uce.request.SubscriptionTerminatedHelper.TerminatedResult; import com.android.ims.rcs.uce.request.UceRequestManager.RequestManagerCallback; +import com.android.ims.rcs.uce.UceStatsWriter; import com.android.internal.annotations.VisibleForTesting; import java.util.ArrayList; @@ -53,7 +54,13 @@ public class SubscribeRequestCoordinator extends UceRequestCoordinator { * The builder of the SubscribeRequestCoordinator class. */ public Builder(int subId, Collection<UceRequest> requests, RequestManagerCallback c) { - mRequestCoordinator = new SubscribeRequestCoordinator(subId, requests, c); + mRequestCoordinator = new SubscribeRequestCoordinator(subId, requests, c, + UceStatsWriter.getInstance()); + } + @VisibleForTesting + public Builder(int subId, Collection<UceRequest> requests, RequestManagerCallback c, + UceStatsWriter instance) { + mRequestCoordinator = new SubscribeRequestCoordinator(subId, requests, c, instance); } /** @@ -154,9 +161,12 @@ public class SubscribeRequestCoordinator extends UceRequestCoordinator { // The callback to notify the result of the capabilities request. private volatile IRcsUceControllerCallback mCapabilitiesCallback; + private final UceStatsWriter mUceStatsWriter; + private SubscribeRequestCoordinator(int subId, Collection<UceRequest> requests, - RequestManagerCallback requestMgrCallback) { + RequestManagerCallback requestMgrCallback, UceStatsWriter instance) { super(subId, requests, requestMgrCallback); + mUceStatsWriter = instance; logd("SubscribeRequestCoordinator: created"); } @@ -248,6 +258,10 @@ public class SubscribeRequestCoordinator extends UceRequestCoordinator { // Finish this request. request.onFinish(); + int commandErrorCode = response.getCommandError().orElse(0); + mUceStatsWriter.setUceEvent(mSubId, UceStatsWriter.SUBSCRIBE_EVENT, + false, commandErrorCode, 0); + // Remove this request from the activated collection and notify RequestManager. Long taskId = request.getTaskId(); RequestResult requestResult = sCommandErrorCreator.createRequestResult(taskId, response, @@ -263,6 +277,9 @@ public class SubscribeRequestCoordinator extends UceRequestCoordinator { CapabilityRequestResponse response = request.getRequestResponse(); logd("handleNetworkResponse: " + response.toString()); + int respCode = response.getNetworkRespSipCode().orElse(0); + mUceStatsWriter.setSubscribeResponse(mSubId, request.getTaskId(), respCode); + // Refresh the device state with the request result. response.getResponseSipCode().ifPresent(sipCode -> { String reason = response.getResponseReason().orElse(""); @@ -379,6 +396,7 @@ public class SubscribeRequestCoordinator extends UceRequestCoordinator { return; } + mUceStatsWriter.setPresenceNotifyEvent(mSubId, taskId, updatedCapList); // Save the updated capabilities to the cache. mRequestManagerCallback.saveCapabilities(updatedCapList); @@ -402,6 +420,8 @@ public class SubscribeRequestCoordinator extends UceRequestCoordinator { return; } + mUceStatsWriter.setPresenceNotifyEvent(mSubId, taskId, terminatedResources); + // Save the terminated capabilities to the cache. mRequestManagerCallback.saveCapabilities(terminatedResources); @@ -442,6 +462,7 @@ public class SubscribeRequestCoordinator extends UceRequestCoordinator { // Remove this request from the activated collection and notify RequestManager. Long taskId = request.getTaskId(); + mUceStatsWriter.setSubscribeTerminated(mSubId, taskId, response.getTerminatedReason()); RequestResult requestResult = sTerminatedCreator.createRequestResult(taskId, response, mRequestManagerCallback); moveRequestToFinishedCollection(taskId, requestResult); |