Merge "Support bulk capability exchange in UCE"
diff --git a/src/java/com/android/ims/FeatureConnection.java b/src/java/com/android/ims/FeatureConnection.java
index 7103043..748ae57 100644
--- a/src/java/com/android/ims/FeatureConnection.java
+++ b/src/java/com/android/ims/FeatureConnection.java
@@ -32,6 +32,8 @@
import com.android.internal.annotations.VisibleForTesting;
+import java.util.NoSuchElementException;
+
/**
* Base class of MmTelFeatureConnection and RcsFeatureConnection.
*/
@@ -79,7 +81,8 @@
mBinder.linkToDeath(mDeathRecipient, 0);
}
} catch (RemoteException e) {
- // No need to do anything if the binder is already dead.
+ Log.w(TAG, "setBinder: linkToDeath on already dead Binder, setting null");
+ mBinder = null;
}
}
}
@@ -103,8 +106,12 @@
synchronized (mLock) {
if (mIsAvailable) {
mIsAvailable = false;
- if (mBinder != null) {
- mBinder.unlinkToDeath(mDeathRecipient, 0);
+ try {
+ if (mBinder != null) {
+ mBinder.unlinkToDeath(mDeathRecipient, 0);
+ }
+ } catch (NoSuchElementException e) {
+ Log.w(TAG, "onRemovedOrDied: unlinkToDeath called on unlinked Binder.");
}
}
}
diff --git a/src/java/com/android/ims/ImsCall.java b/src/java/com/android/ims/ImsCall.java
index ea9318b..0d5b396 100755
--- a/src/java/com/android/ims/ImsCall.java
+++ b/src/java/com/android/ims/ImsCall.java
@@ -32,6 +32,7 @@
import android.telephony.TelephonyManager;
import android.telephony.ims.ImsCallProfile;
import android.telephony.ims.ImsCallSession;
+import android.telephony.ims.ImsCallSessionListener;
import android.telephony.ims.ImsConferenceState;
import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.ImsStreamMediaProfile;
@@ -94,11 +95,21 @@
*/
public static class Listener {
/**
- * Called when a request is sent out to initiate a new call
- * and 1xx response is received from the network.
+ * Called after the network first begins to establish the call session and is now connecting
+ * to the remote party.
* The default implementation calls {@link #onCallStateChanged}.
- *
- * @param call the call object that carries out the IMS call
+ * <p/>
+ * see: {@link ImsCallSessionListener#callSessionInitiating}
+ */
+ public void onCallInitiating(ImsCall call) {
+ onCallStateChanged(call);
+ }
+
+ /**
+ * Called after the network has contacted the remote party.
+ * The default implementation calls {@link #onCallStateChanged}.
+ * <p/>
+ * see: {@link ImsCallSessionListener#callSessionProgressing}
*/
public void onCallProgressing(ImsCall call) {
onCallStateChanged(call);
@@ -2436,6 +2447,32 @@
@VisibleForTesting
public class ImsCallSessionListenerProxy extends ImsCallSession.Listener {
@Override
+ public void callSessionInitiating(ImsCallSession session, ImsCallProfile profile) {
+ logi("callSessionInitiating :: session=" + session + " profile=" + profile);
+ if (isTransientConferenceSession(session)) {
+ // If it is a transient (conference) session, there is no action for this signal.
+ logi("callSessionInitiating :: not supported for transient conference session=" +
+ session);
+ return;
+ }
+
+ ImsCall.Listener listener;
+
+ synchronized(ImsCall.this) {
+ listener = mListener;
+ setCallProfile(profile);
+ }
+
+ if (listener != null) {
+ try {
+ listener.onCallInitiating(ImsCall.this);
+ } catch (Throwable t) {
+ loge("callSessionInitiating :: ", t);
+ }
+ }
+ }
+
+ @Override
public void callSessionProgressing(ImsCallSession session, ImsStreamMediaProfile profile) {
logi("callSessionProgressing :: session=" + session + " profile=" + profile);
diff --git a/src/java/com/android/ims/ImsManager.java b/src/java/com/android/ims/ImsManager.java
index 867a273..3dfa7fc 100644
--- a/src/java/com/android/ims/ImsManager.java
+++ b/src/java/com/android/ims/ImsManager.java
@@ -50,6 +50,7 @@
import android.telephony.ims.aidl.IImsRegistration;
import android.telephony.ims.aidl.IImsRegistrationCallback;
import android.telephony.ims.aidl.IImsSmsListener;
+import android.telephony.ims.aidl.IRcsConfigCallback;
import android.telephony.ims.aidl.ISipTransport;
import android.telephony.ims.feature.CapabilityChangeRequest;
import android.telephony.ims.feature.ImsFeature;
@@ -865,6 +866,14 @@
}
/**
+ * Returns whether the user sets call composer setting per sub.
+ */
+ public boolean isCallComposerEnabledByUser() {
+ return new TelephonyManager(mContext, getSubId()).getCallComposerStatus() ==
+ TelephonyManager.CALL_COMPOSER_STATUS_ON;
+ }
+
+ /**
* Change persistent VT enabled setting
*
* @deprecated Does not support MSIM devices. Please use {@link #setVtSetting(boolean)} instead.
@@ -1465,6 +1474,7 @@
updateVolteFeatureValue(request);
updateWfcFeatureAndProvisionedValues(request);
updateVideoCallFeatureValue(request);
+ updateCallComposerFeatureValue(request);
// Only turn on IMS for RTT if there's an active subscription present. If not, the
// modem will be in emergency-call-only mode and will use separate signaling to
// establish an RTT emergency call.
@@ -1642,6 +1652,31 @@
}
/**
+ * Update call composer capability
+ */
+ private void updateCallComposerFeatureValue(CapabilityChangeRequest request) {
+ boolean isUserSetEnabled = isCallComposerEnabledByUser();
+ boolean isCarrierConfigEnabled = getBooleanCarrierConfig(
+ CarrierConfigManager.KEY_SUPPORTS_CALL_COMPOSER_BOOL);
+
+ boolean isFeatureOn = isUserSetEnabled && isCarrierConfigEnabled;
+
+ log("updateCallComposerFeatureValue: isUserSetEnabled = " + isUserSetEnabled
+ + ", isCarrierConfigEnabled = " + isCarrierConfigEnabled
+ + ", isFeatureOn = " + isFeatureOn);
+
+ if (isFeatureOn) {
+ request.addCapabilitiesToEnableForTech(
+ MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_CALL_COMPOSER,
+ ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
+ } else {
+ request.addCapabilitiesToDisableForTech(
+ MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_CALL_COMPOSER,
+ ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
+ }
+ }
+
+ /**
* Do NOT use this directly, instead use {@link #getInstance(Context, int)}.
*/
private ImsManager(Context context, int phoneId) {
@@ -2828,6 +2863,47 @@
provisionStatus);
}
+ /**
+ * Adds a callback of RCS provisioning for a specified subscription.
+ * @param callback A {@link android.telephony.ims.aidl.IRcsConfigCallback}
+ * for RCS provisioning change.
+ * @param subId The subscription that is associated with the callback.
+ * @throws IllegalStateException when the {@link ImsService} connection is not available.
+ * @throws IllegalArgumentException when the {@link IRcsConfigCallback} argument is null.
+ */
+ public void addRcsProvisioningCallbackForSubscription(IRcsConfigCallback callback, int subId) {
+ if (callback == null) {
+ throw new IllegalArgumentException("provisioning callback can't be null");
+ }
+
+ mMmTelConnectionRef.get().addRcsProvisioningCallbackForSubscription(callback, subId);
+ log("Capability Callback registered for subscription.");
+ }
+
+ /**
+ * Removes a previously registered {@link android.telephony.ims.aidl.IRcsConfigCallback}.
+ * @throws IllegalStateException when the {@link ImsService} connection is not available.
+ * @throws IllegalArgumentException when the {@link IRcsConfigCallback} argument is null.
+ */
+ public void removeRcsProvisioningCallbackForSubscription(
+ IRcsConfigCallback callback, int subId) {
+ if (callback == null) {
+ throw new IllegalArgumentException("provisioning callback can't be null");
+ }
+
+ mMmTelConnectionRef.get().removeRcsProvisioningCallbackForSubscription(callback, subId);
+ }
+
+ /**
+ * Removes all RCS provisioning callbacks
+ *
+ * <p>This method is called when default message application change or some other event
+ * which need force to remove all RCS provisioning callbacks.
+ */
+ public void clearRcsProvisioningCallbacks() {
+ mMmTelConnectionRef.get().clearRcsProvisioningCallbacks();
+ }
+
private boolean isDataEnabled() {
return new TelephonyManager(mContext, getSubId()).isDataConnectionAllowed();
}
diff --git a/src/java/com/android/ims/MmTelFeatureConnection.java b/src/java/com/android/ims/MmTelFeatureConnection.java
index cc7eace..d4fd2f3 100644
--- a/src/java/com/android/ims/MmTelFeatureConnection.java
+++ b/src/java/com/android/ims/MmTelFeatureConnection.java
@@ -32,6 +32,7 @@
import android.telephony.ims.aidl.IImsRegistration;
import android.telephony.ims.aidl.IImsRegistrationCallback;
import android.telephony.ims.aidl.IImsSmsListener;
+import android.telephony.ims.aidl.IRcsConfigCallback;
import android.telephony.ims.aidl.ISipTransport;
import android.telephony.ims.feature.CapabilityChangeRequest;
import android.telephony.ims.feature.ImsFeature;
@@ -197,6 +198,52 @@
}
}
+ private class RcsProvisioningCallbackManager
+ extends ImsCallbackAdapterManager<IRcsConfigCallback> {
+ public RcsProvisioningCallbackManager (Context context, Object lock) {
+ super(context, lock, mSlotId);
+ }
+
+ @Override
+ public void registerCallback(IRcsConfigCallback localCallback) {
+ IImsConfig binder = getConfig();
+ if (binder == null) {
+ // Config interface is not currently available.
+ Log.w(TAG + " [" + mSlotId + "]",
+ "RcsProvisioningCallbackManager - couldn't register,"
+ + " binder is null.");
+ throw new IllegalStateException("RcsConfig is not available!");
+ }
+ try {
+ binder.addRcsConfigCallback(localCallback);
+ }catch (RemoteException e) {
+ throw new IllegalStateException("ImsService is not available!");
+ }
+ }
+
+ @Override
+ public void unregisterCallback(IRcsConfigCallback localCallback) {
+ IImsConfig binder = getConfig();
+ if (binder != null) {
+ try {
+ binder.removeRcsConfigCallback(localCallback);
+ } catch (RemoteException e) {
+ Log.w(TAG + " [" + mSlotId + "]", "RcsProvisioningCallbackManager - couldn't"
+ + " unregister, binder is dead.");
+ }
+ } else {
+ Log.w(TAG + " [" + mSlotId + "]", "RcsProvisioningCallbackManager - couldn't"
+ + " unregister, binder is null.");
+ }
+ try {
+ localCallback.onRemoved();
+ } catch (RemoteException e) {
+ Log.w(TAG + " [" + mSlotId + "]", "RcsProvisioningCallbackManager - couldn't"
+ + " notify onRemoved, binder is dead.");
+ }
+ }
+ }
+
// Updated by IImsServiceFeatureCallback when FEATURE_EMERGENCY_MMTEL is sent.
private boolean mSupportsEmergencyCalling = false;
// MMTEL specific binder Interfaces
@@ -207,6 +254,7 @@
private final ImsRegistrationCallbackAdapter mRegistrationCallbackManager;
private final CapabilityCallbackManager mCapabilityCallbackManager;
private final ProvisioningCallbackManager mProvisioningCallbackManager;
+ private final RcsProvisioningCallbackManager mRcsProvisioningCallbackManager;
public MmTelFeatureConnection(Context context, int slotId, IImsMmTelFeature f,
IImsConfig c, IImsRegistration r, ISipTransport s) {
@@ -216,6 +264,7 @@
mRegistrationCallbackManager = new ImsRegistrationCallbackAdapter(context, mLock);
mCapabilityCallbackManager = new CapabilityCallbackManager(context, mLock);
mProvisioningCallbackManager = new ProvisioningCallbackManager(context, mLock);
+ mRcsProvisioningCallbackManager = new RcsProvisioningCallbackManager(context, mLock);
}
@Override
@@ -464,6 +513,20 @@
}
}
+ public void addRcsProvisioningCallbackForSubscription(IRcsConfigCallback callback,
+ int subId) {
+ mRcsProvisioningCallbackManager.addCallbackForSubscription(callback, subId);
+ }
+
+ public void removeRcsProvisioningCallbackForSubscription(IRcsConfigCallback callback,
+ int subId) {
+ mRcsProvisioningCallbackManager.removeCallbackForSubscription(callback , subId);
+ }
+
+ public void clearRcsProvisioningCallbacks() {
+ mRcsProvisioningCallbackManager.close();
+ }
+
@Override
protected Integer retrieveFeatureState() {
if (mBinder != null) {
diff --git a/src/java/com/android/ims/RcsFeatureConnection.java b/src/java/com/android/ims/RcsFeatureConnection.java
index 1dfc1aa..368f22e 100644
--- a/src/java/com/android/ims/RcsFeatureConnection.java
+++ b/src/java/com/android/ims/RcsFeatureConnection.java
@@ -140,7 +140,8 @@
public void setCapabilityExchangeEventListener(ICapabilityExchangeEventListener listener)
throws RemoteException {
synchronized (mLock) {
- checkServiceIsReady();
+ // Only check if service is alive. The feature status may not be READY.
+ checkServiceIsAlive();
getServiceInterface(mBinder).setCapabilityExchangeEventListener(listener);
}
}
@@ -153,6 +154,15 @@
}
}
+ private void checkServiceIsAlive() throws RemoteException {
+ if (!sImsSupportedOnDevice) {
+ throw new RemoteException("IMS is not supported on this device.");
+ }
+ if (!isBinderAlive()) {
+ throw new RemoteException("ImsServiceProxy is not alive.");
+ }
+ }
+
public int queryCapabilityStatus() throws RemoteException {
synchronized (mLock) {
checkServiceIsReady();
diff --git a/src/java/com/android/ims/RcsFeatureManager.java b/src/java/com/android/ims/RcsFeatureManager.java
index cc519e8..b2faf90 100644
--- a/src/java/com/android/ims/RcsFeatureManager.java
+++ b/src/java/com/android/ims/RcsFeatureManager.java
@@ -34,6 +34,7 @@
import android.telephony.ims.aidl.IImsCapabilityCallback;
import android.telephony.ims.aidl.IImsRcsController;
import android.telephony.ims.aidl.IImsRcsFeature;
+import android.telephony.ims.aidl.IImsRegistration;
import android.telephony.ims.aidl.IImsRegistrationCallback;
import android.telephony.ims.aidl.IOptionsRequestCallback;
import android.telephony.ims.aidl.IPublishResponseCallback;
@@ -160,8 +161,7 @@
/**
* Opens a persistent connection to the RcsFeature. This must be called before the RcsFeature
- * can be used to communicate. Triggers a {@link RcsFeature#onFeatureReady()} call on the
- * service side.
+ * can be used to communicate.
*/
public void openConnection() throws android.telephony.ims.ImsException {
try {
@@ -327,6 +327,10 @@
return mRcsFeatureConnection.getSipTransport();
}
+ public IImsRegistration getImsRegistration() {
+ return mRcsFeatureConnection.getRegistration();
+ }
+
/**
* Query for the specific capability.
*/
@@ -479,7 +483,7 @@
if (capabilityType == CAPABILITY_OPTIONS) {
return b.getBoolean(CarrierConfigManager.KEY_USE_RCS_SIP_OPTIONS_BOOL, false);
} else if (capabilityType == CAPABILITY_PRESENCE) {
- return b.getBoolean(CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL, false);
+ return b.getBoolean(CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, false);
}
return false;
}
diff --git a/src/java/com/android/ims/rcs/uce/UceController.java b/src/java/com/android/ims/rcs/uce/UceController.java
index ad04996..4d01899 100644
--- a/src/java/com/android/ims/rcs/uce/UceController.java
+++ b/src/java/com/android/ims/rcs/uce/UceController.java
@@ -26,7 +26,6 @@
import android.telephony.ims.RcsUceAdapter;
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;
@@ -45,6 +44,7 @@
import com.android.ims.rcs.uce.presence.subscribe.SubscribeController;
import com.android.ims.rcs.uce.presence.subscribe.SubscribeControllerImpl;
import com.android.ims.rcs.uce.request.UceRequestManager;
+import com.android.ims.rcs.uce.util.UceUtils;
import com.android.internal.annotations.VisibleForTesting;
import java.time.Duration;
@@ -59,7 +59,7 @@
*/
public class UceController {
- private static final String LOG_TAG = "UceController";
+ private static final String LOG_TAG = UceUtils.getLogPrefix() + "UceController";
/**
* The callback interface is called by the internal controllers to receive information from
@@ -579,8 +579,7 @@
} else {
mAllowedTimestamp = Instant.now().plus(retryAfterMillis, ChronoUnit.MILLIS);
}
- Log.d(LOG_TAG, "forbidUceRequest: " + mIsForbidden
- + ", time=" + mAllowedTimestamp);
+ Log.d(LOG_TAG, "forbidUceRequest: " + mIsForbidden + ",time=" + mAllowedTimestamp);
}
}
diff --git a/src/java/com/android/ims/rcs/uce/presence/publish/DeviceCapabilityInfo.java b/src/java/com/android/ims/rcs/uce/presence/publish/DeviceCapabilityInfo.java
index b81aea8..389f104 100644
--- a/src/java/com/android/ims/rcs/uce/presence/publish/DeviceCapabilityInfo.java
+++ b/src/java/com/android/ims/rcs/uce/presence/publish/DeviceCapabilityInfo.java
@@ -18,10 +18,8 @@
import android.content.Context;
import android.net.Uri;
-import android.telecom.PhoneAccount;
import android.telecom.TelecomManager;
import android.telephony.AccessNetworkConstants;
-import android.telephony.TelephonyManager;
import android.telephony.ims.RcsContactPresenceTuple;
import android.telephony.ims.RcsContactPresenceTuple.ServiceCapabilities;
import android.telephony.ims.RcsContactUceCapability;
@@ -30,11 +28,13 @@
import android.telephony.ims.feature.MmTelFeature.MmTelCapabilities;
import android.util.Log;
+import com.android.ims.rcs.uce.util.UceUtils;
+
/**
* Stores the device's capabilities information.
*/
public class DeviceCapabilityInfo {
- private static final String LOG_TAG = "DeviceCapabilityInfo";
+ private static final String LOG_TAG = UceUtils.getLogPrefix() + "DeviceCapabilityInfo";
private final int mSubId;
@@ -208,11 +208,13 @@
boolean oldVoWifiAvailable = isVoWifiAvailable(mMmtelNetworkRegType, mMmTelCapabilities);
boolean oldVtAvailable = isVtAvailable(mMmtelNetworkRegType, mMmTelCapabilities);
boolean oldViWifiAvailable = isViWifiAvailable(mMmtelNetworkRegType, mMmTelCapabilities);
+ boolean oldCallComposerAvailable = isCallComposerAvailable(mMmTelCapabilities);
boolean volteAvailable = isVolteAvailable(mMmtelNetworkRegType, capabilities);
boolean voWifiAvailable = isVoWifiAvailable(mMmtelNetworkRegType, capabilities);
boolean vtAvailable = isVtAvailable(mMmtelNetworkRegType, capabilities);
boolean viWifiAvailable = isViWifiAvailable(mMmtelNetworkRegType, capabilities);
+ boolean callComposerAvailable = isCallComposerAvailable(capabilities);
logd("updateMmtelCapabilitiesChanged: from " + mMmTelCapabilities + " to " + capabilities);
@@ -222,7 +224,8 @@
if (oldVolteAvailable != volteAvailable
|| oldVoWifiAvailable != voWifiAvailable
|| oldVtAvailable != vtAvailable
- || oldViWifiAvailable != viWifiAvailable) {
+ || oldViWifiAvailable != viWifiAvailable
+ || oldCallComposerAvailable != callComposerAvailable) {
return true;
}
return false;
@@ -248,6 +251,11 @@
&& capabilities.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO);
}
+ private boolean isCallComposerAvailable(MmTelCapabilities capabilities) {
+ return capabilities.isCapable(
+ MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_CALL_COMPOSER);
+ }
+
/**
* Get the device's capabilities.
*/
@@ -266,10 +274,20 @@
RcsContactPresenceTuple.SERVICE_ID_MMTEL, "1.0");
tupleBuilder.addContactUri(uri).addServiceCapabilities(servCapsBuilder.build());
+ RcsContactPresenceTuple.Builder callComposerTupleBuilder =
+ new RcsContactPresenceTuple.Builder(
+ RcsContactPresenceTuple.TUPLE_BASIC_STATUS_OPEN,
+ RcsContactPresenceTuple.SERVICE_ID_CALL_COMPOSER, "2.0");
+ callComposerTupleBuilder.addContactUri(uri).addServiceCapabilities(
+ servCapsBuilder.build());
+
PresenceBuilder presenceBuilder = new PresenceBuilder(uri,
RcsContactUceCapability.SOURCE_TYPE_CACHED,
RcsContactUceCapability.REQUEST_RESULT_FOUND);
presenceBuilder.addCapabilityTuple(tupleBuilder.build());
+ if (hasCallComposerCapability()) {
+ presenceBuilder.addCapabilityTuple(callComposerTupleBuilder.build());
+ }
return presenceBuilder.build();
}
@@ -292,6 +310,15 @@
return false;
}
+ // Check if the device has the Call Composer capability
+ private synchronized boolean hasCallComposerCapability() {
+ if (mMmTelCapabilities != null && mMmTelCapabilities.isCapable(
+ MmTelCapabilities.CAPABILITY_TYPE_CALL_COMPOSER)) {
+ return true;
+ }
+ return false;
+ }
+
private synchronized MmTelCapabilities deepCopyCapabilities(MmTelCapabilities capabilities) {
MmTelCapabilities mmTelCapabilities = new MmTelCapabilities();
if (capabilities.isCapable(MmTelCapabilities.CAPABILITY_TYPE_VOICE)) {
@@ -306,6 +333,9 @@
if (capabilities.isCapable(MmTelCapabilities.CAPABILITY_TYPE_SMS)) {
mmTelCapabilities.addCapabilities(MmTelCapabilities.CAPABILITY_TYPE_SMS);
}
+ if (capabilities.isCapable(MmTelCapabilities.CAPABILITY_TYPE_CALL_COMPOSER)) {
+ mmTelCapabilities.addCapabilities(MmTelCapabilities.CAPABILITY_TYPE_CALL_COMPOSER);
+ }
return mmTelCapabilities;
}
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 d1b5275..a9d5d90 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
@@ -40,6 +40,7 @@
import android.util.Log;
import com.android.ims.rcs.uce.presence.publish.PublishController.PublishControllerCallback;
+import com.android.ims.rcs.uce.util.UceUtils;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.util.HandlerExecutor;
@@ -49,7 +50,11 @@
*/
public class DeviceCapabilityListener {
- private static final String LOG_TAG = "DeviceCapListener";
+ private static final String LOG_TAG = UceUtils.getLogPrefix() + "DeviceCapListener";
+
+ // Delay to send the registered changed because the registered state changed of MMTEL and RCS
+ // may be called at the same time.
+ private static final long DELAY_SEND_IMS_REGISTERED_CHANGED_MSG = 500L;
/**
* Used to inject ImsMmTelManager instances for testing.
@@ -477,7 +482,8 @@
private void handleImsMmtelRegistered(int imsTransportType) {
mCapabilityInfo.updateImsMmtelRegistered(imsTransportType);
mCallback.requestPublishFromInternal(
- PublishController.PUBLISH_TRIGGER_MMTEL_REGISTERED, 0L);
+ PublishController.PUBLISH_TRIGGER_MMTEL_REGISTERED,
+ DELAY_SEND_IMS_REGISTERED_CHANGED_MSG);
}
/*
@@ -490,8 +496,8 @@
}
private void handleMmtelCapabilitiesStatusChanged(MmTelCapabilities capabilities) {
- logi("MMTel capabilities status changed");
boolean isChanged = mCapabilityInfo.updateMmtelCapabilitiesChanged(capabilities);
+ logi("MMTel capabilities status changed: isChanged=" + isChanged);
if (isChanged) {
mCallback.requestPublishFromInternal(
PublishController.PUBLISH_TRIGGER_MMTEL_CAPABILITY_CHANGE, 0L);
@@ -503,7 +509,9 @@
*/
private void handleImsRcsRegistered(int imsTransportType) {
mCapabilityInfo.updateImsRcsRegistered(imsTransportType);
- mCallback.requestPublishFromInternal(PublishController.PUBLISH_TRIGGER_RCS_REGISTERED, 0L);
+ mCallback.requestPublishFromInternal(
+ PublishController.PUBLISH_TRIGGER_RCS_REGISTERED,
+ DELAY_SEND_IMS_REGISTERED_CHANGED_MSG);
}
/*
diff --git a/src/java/com/android/ims/rcs/uce/presence/publish/PublishController.java b/src/java/com/android/ims/rcs/uce/presence/publish/PublishController.java
index e4e33f0..f55a885 100644
--- a/src/java/com/android/ims/rcs/uce/presence/publish/PublishController.java
+++ b/src/java/com/android/ims/rcs/uce/presence/publish/PublishController.java
@@ -26,6 +26,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.time.Instant;
/**
* The interface related to the PUBLISH request.
@@ -118,7 +119,7 @@
/**
* Update the publish request result.
*/
- void updatePublishRequestResult(int publishState);
+ void updatePublishRequestResult(int publishState, Instant updatedTimestamp);
}
/**
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 39494f9..9003bfd 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
@@ -31,11 +31,20 @@
import com.android.ims.RcsFeatureManager;
import com.android.ims.rcs.uce.UceController.UceControllerCallback;
+import com.android.ims.rcs.uce.util.UceUtils;
import com.android.internal.annotations.VisibleForTesting;
+import java.lang.ref.WeakReference;
+import java.time.Instant;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * The implementation of PublishController.
+ */
public class PublishControllerImpl implements PublishController {
- private static final String LOG_TAG = "PublishController";
+ private static final String LOG_TAG = UceUtils.getLogPrefix() + "PublishController";
/**
* Used to inject PublishProcessor instances for testing.
@@ -63,6 +72,8 @@
// The device publish state
private @PublishState int mPublishState;
+ // The timestamp of updating the publish state
+ private Instant mPublishStateUpdatedTime = Instant.now();
// The callbacks to notify publish state changed.
private RemoteCallbackList<IRcsUcePublishStateCallback> mPublishStateCallbacks;
@@ -108,7 +119,7 @@
mPublishState = RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED;
mPublishStateCallbacks = new RemoteCallbackList<>();
- mPublishHandler = new PublishHandler(looper);
+ mPublishHandler = new PublishHandler(this, looper);
mDeviceCapabilityInfo = new DeviceCapabilityInfo(mSubId);
initPublishProcessor();
@@ -167,7 +178,11 @@
synchronized (mPublishStateLock) {
if (mIsDestroyedFlag) return;
mPublishStateCallbacks.register(c);
+ logd("registerPublishStateCallback: size="
+ + mPublishStateCallbacks.getRegisteredCallbackCount());
}
+ // Notify the current publish state
+ mPublishHandler.onNotifyCurrentPublishState(c);
}
/**
@@ -201,7 +216,8 @@
public void onUnpublish() {
logd("onUnpublish");
if (mIsDestroyedFlag) return;
- mPublishHandler.onPublishStateChanged(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED);
+ mPublishHandler.onPublishStateChanged(RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED,
+ Instant.now());
}
@Override
@@ -220,13 +236,15 @@
@Override
public void onRequestCommandError(PublishRequestResponse requestResponse) {
- logd("onRequestCommandError: taskId=" + requestResponse.getTaskId());
+ logd("onRequestCommandError: taskId=" + requestResponse.getTaskId()
+ + ", time=" + requestResponse.getResponseTimestamp());
mPublishHandler.onRequestCommandError(requestResponse);
}
@Override
public void onRequestNetworkResp(PublishRequestResponse requestResponse) {
- logd("onRequestNetworkResp: taskId=" + requestResponse.getTaskId());
+ logd("onRequestNetworkResp: taskId=" + requestResponse.getTaskId()
+ + ", time=" + requestResponse.getResponseTimestamp());
mPublishHandler.onRequestNetworkResponse(requestResponse);
}
@@ -243,9 +261,10 @@
}
@Override
- public void updatePublishRequestResult(@PublishState int publishState) {
- logd("updatePublishRequestResult: " + publishState);
- mPublishHandler.onPublishStateChanged(publishState);
+ public void updatePublishRequestResult(@PublishState int publishState,
+ Instant updatedTime) {
+ logd("updatePublishRequestResult: " + publishState + ", time=" + updatedTime);
+ mPublishHandler.onPublishStateChanged(publishState, updatedTime);
}
};
@@ -254,49 +273,63 @@
*/
@Override
public void requestPublishCapabilitiesFromService(int triggerType) {
- logi("Receive the publish request from service: " + triggerType);
+ logi("Receive the publish request from service: service trigger type=" + triggerType);
mPublishHandler.requestPublish(PublishController.PUBLISH_TRIGGER_SERVICE);
}
- private class PublishHandler extends Handler {
+ private static class PublishHandler extends Handler {
private static final int MSG_PUBLISH_STATE_CHANGED = 1;
- private static final int MSG_REQUEST_PUBLISH = 2;
- private static final int MSG_REQUEST_CMD_ERROR = 3;
- private static final int MSG_REQUEST_SIP_RESPONSE = 4;
- private static final int MSG_REQUEST_CANCELED = 5;
+ private static final int MSG_NOTIFY_CURRENT_PUBLISH_STATE = 2;
+ private static final int MSG_REQUEST_PUBLISH = 3;
+ private static final int MSG_REQUEST_CMD_ERROR = 4;
+ private static final int MSG_REQUEST_NETWORK_RESPONSE = 5;
+ private static final int MSG_REQUEST_CANCELED = 6;
- public PublishHandler(Looper looper) {
+ private final WeakReference<PublishControllerImpl> mPublishControllerRef;
+
+ public PublishHandler(PublishControllerImpl publishController, Looper looper) {
super(looper);
+ mPublishControllerRef = new WeakReference<>(publishController);
}
@Override
public void handleMessage(Message message) {
- if (mIsDestroyedFlag) return;
- logd("handleMessage: " + message.what);
+ PublishControllerImpl publishCtrl = mPublishControllerRef.get();
+ if (publishCtrl == null) {
+ return;
+ }
+ if (publishCtrl.mIsDestroyedFlag) return;
+ publishCtrl.logd("handleMessage: " + EVENT_DESCRIPTION.get(message.what));
switch (message.what) {
case MSG_PUBLISH_STATE_CHANGED:
int newPublishState = message.arg1;
- handlePublishStateChangedMessage(newPublishState);
+ Instant updatedTimestamp = (Instant) message.obj;
+ publishCtrl.handlePublishStateChangedMessage(newPublishState, updatedTimestamp);
+ break;
+
+ case MSG_NOTIFY_CURRENT_PUBLISH_STATE:
+ IRcsUcePublishStateCallback c = (IRcsUcePublishStateCallback) message.obj;
+ publishCtrl.handleNotifyCurrentPublishStateMessage(c);
break;
case MSG_REQUEST_PUBLISH:
int type = (Integer) message.obj;
- handleRequestPublishMessage(type);
+ publishCtrl.handleRequestPublishMessage(type);
break;
case MSG_REQUEST_CMD_ERROR:
PublishRequestResponse cmdErrorResponse = (PublishRequestResponse) message.obj;
- mPublishProcessor.onCommandError(cmdErrorResponse);
+ publishCtrl.mPublishProcessor.onCommandError(cmdErrorResponse);
break;
- case MSG_REQUEST_SIP_RESPONSE:
+ case MSG_REQUEST_NETWORK_RESPONSE:
PublishRequestResponse networkResponse = (PublishRequestResponse) message.obj;
- mPublishProcessor.onNetworkResponse(networkResponse);
+ publishCtrl.mPublishProcessor.onNetworkResponse(networkResponse);
break;
case MSG_REQUEST_CANCELED:
long taskId = (Long) message.obj;
- handleRequestCanceledMessage(taskId);
+ publishCtrl.handleRequestCanceledMessage(taskId);
break;
}
}
@@ -305,17 +338,25 @@
* Remove all the messages from the handler.
*/
public void onDestroy() {
- removeMessages(MSG_PUBLISH_STATE_CHANGED);
- removeMessages(MSG_REQUEST_PUBLISH);
+ removeCallbacksAndMessages(null);
}
/**
* Send the message to notify the publish state is changed.
*/
- public void onPublishStateChanged(@PublishState int publishState) {
+ public void onPublishStateChanged(@PublishState int publishState,
+ @NonNull Instant updatedTimestamp) {
Message message = obtainMessage();
message.what = MSG_PUBLISH_STATE_CHANGED;
message.arg1 = publishState;
+ message.obj = updatedTimestamp;
+ sendMessage(message);
+ }
+
+ public void onNotifyCurrentPublishState(IRcsUcePublishStateCallback callback) {
+ Message message = obtainMessage();
+ message.what = MSG_NOTIFY_CURRENT_PUBLISH_STATE;
+ message.obj = callback;
sendMessage(message);
}
@@ -330,11 +371,19 @@
* Send the request publish message with the delay.
*/
public void requestPublish(@PublishTriggerType int type, long delay) {
- if (mIsDestroyedFlag) return;
- logd("requestPublish: " + type + ", delay=" + delay);
+ PublishControllerImpl publishCtrl = mPublishControllerRef.get();
+ if (publishCtrl == null) {
+ return;
+ }
+ if (publishCtrl.mIsDestroyedFlag) return;
+ publishCtrl.logd("requestPublish: " + type + ", delay=" + delay);
- // Remove existing publish request.
- removeMessages(MSG_REQUEST_PUBLISH, (Integer) type);
+ // Don't send duplicated publish request because it always publish the latest device
+ // capabilities.
+ if (hasMessages(MSG_REQUEST_PUBLISH)) {
+ publishCtrl.logd("requestPublish: Skip. there is already a request in the queue");
+ return;
+ }
Message message = obtainMessage();
message.what = MSG_REQUEST_PUBLISH;
@@ -347,8 +396,11 @@
}
public void onRequestCommandError(PublishRequestResponse requestResponse) {
- if (mIsDestroyedFlag) return;
-
+ PublishControllerImpl publishCtrl = mPublishControllerRef.get();
+ if (publishCtrl == null) {
+ return;
+ }
+ if (publishCtrl.mIsDestroyedFlag) return;
Message message = obtainMessage();
message.what = MSG_REQUEST_CMD_ERROR;
message.obj = requestResponse;
@@ -356,16 +408,23 @@
}
public void onRequestNetworkResponse(PublishRequestResponse requestResponse) {
- if (mIsDestroyedFlag) return;
-
+ PublishControllerImpl publishCtrl = mPublishControllerRef.get();
+ if (publishCtrl == null) {
+ return;
+ }
+ if (publishCtrl.mIsDestroyedFlag) return;
Message message = obtainMessage();
- message.what = MSG_REQUEST_SIP_RESPONSE;
+ message.what = MSG_REQUEST_NETWORK_RESPONSE;
message.obj = requestResponse;
sendMessage(message);
}
public void setRequestCanceledTimer(long taskId, long delay) {
- if (mIsDestroyedFlag) return;
+ PublishControllerImpl publishCtrl = mPublishControllerRef.get();
+ if (publishCtrl == null) {
+ return;
+ }
+ if (publishCtrl.mIsDestroyedFlag) return;
removeMessages(MSG_REQUEST_CANCELED, (Long) taskId);
Message message = obtainMessage();
@@ -375,21 +434,45 @@
}
public void clearRequestCanceledTimer() {
- if (mIsDestroyedFlag) return;
+ PublishControllerImpl publishCtrl = mPublishControllerRef.get();
+ if (publishCtrl == null) {
+ return;
+ }
+ if (publishCtrl.mIsDestroyedFlag) return;
removeMessages(MSG_REQUEST_CANCELED);
}
+
+ private static Map<Integer, String> EVENT_DESCRIPTION = new HashMap<>();
+ static {
+ EVENT_DESCRIPTION.put(MSG_PUBLISH_STATE_CHANGED, "PUBLISH_STATE_CHANGED");
+ EVENT_DESCRIPTION.put(MSG_NOTIFY_CURRENT_PUBLISH_STATE, "NOTIFY_PUBLISH_STATE");
+ EVENT_DESCRIPTION.put(MSG_REQUEST_PUBLISH, "REQUEST_PUBLISH");
+ EVENT_DESCRIPTION.put(MSG_REQUEST_CMD_ERROR, "REQUEST_CMD_ERROR");
+ EVENT_DESCRIPTION.put(MSG_REQUEST_NETWORK_RESPONSE, "REQUEST_NETWORK_RESPONSE");
+ EVENT_DESCRIPTION.put(MSG_REQUEST_CANCELED, "REQUEST_CANCELED");
+ }
}
/**
* Update the publish state and notify the publish state callback if the new state is different
* from original state.
*/
- private void handlePublishStateChangedMessage(@PublishState int newPublishState) {
+ private void handlePublishStateChangedMessage(@PublishState int newPublishState,
+ Instant updatedTimestamp) {
synchronized (mPublishStateLock) {
if (mIsDestroyedFlag) return;
- logd("publish state changes from " + mPublishState + " to " + newPublishState);
+ // Check if the time of the given publish state is not earlier than existing time.
+ if (updatedTimestamp == null || !updatedTimestamp.isAfter(mPublishStateUpdatedTime)) {
+ logd("handlePublishStateChangedMessage: updatedTimestamp is not allowed: "
+ + mPublishStateUpdatedTime + " to " + updatedTimestamp
+ + ", publishState=" + newPublishState);
+ return;
+ }
+ logd("publish state changes from " + mPublishState + " to " + newPublishState +
+ ", time=" + updatedTimestamp);
if (mPublishState == newPublishState) return;
mPublishState = newPublishState;
+ mPublishStateUpdatedTime = updatedTimestamp;
}
// Trigger the publish state changed in handler thread since it may take time.
@@ -404,6 +487,15 @@
logd("Notify publish state changed: completed");
}
+ private void handleNotifyCurrentPublishStateMessage(IRcsUcePublishStateCallback callback) {
+ if (mIsDestroyedFlag || callback == null) return;
+ try {
+ callback.onPublishStateChanged(getUcePublishState());
+ } catch (RemoteException e) {
+ logw("handleCurrentPublishStateUpdateMessage exception: " + e);
+ }
+ }
+
public void handleRequestPublishMessage(@PublishTriggerType int type) {
if (mIsDestroyedFlag) return;
if (mUceCtrlCallback.isRequestForbiddenByNetwork()) {
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 1a44b89..80b1f50 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
@@ -31,13 +31,14 @@
import com.android.internal.annotations.VisibleForTesting;
import java.io.PrintWriter;
+import java.time.Instant;
/**
* Send the publish request and handle the response of the publish request result.
*/
public class PublishProcessor {
- private static final String LOG_TAG = "PublishProcessor";
+ private static final String LOG_TAG = UceUtils.getLogPrefix() + "PublishProcessor";
// The length of time waiting for the response callback.
private static final long RESPONSE_CALLBACK_WAITING_TIME = 60000L;
@@ -265,7 +266,8 @@
} else {
// Update the publish state if the request is failed and doesn't need to retry.
int publishState = requestResponse.getPublishStateByCmdErrorCode();
- mPublishCtrlCallback.updatePublishRequestResult(publishState);
+ Instant responseTimestamp = requestResponse.getResponseTimestamp();
+ mPublishCtrlCallback.updatePublishRequestResult(publishState, responseTimestamp);
// Check if there is a pending request
checkAndSendPendingRequest();
@@ -309,7 +311,8 @@
}
// Update the publish state if the request doesn't need to retry.
int publishResult = requestResponse.getPublishStateByNetworkResponse();
- mPublishCtrlCallback.updatePublishRequestResult(publishResult);
+ Instant responseTimestamp = requestResponse.getResponseTimestamp();
+ mPublishCtrlCallback.updatePublishRequestResult(publishResult, responseTimestamp);
// Check if there is a pending request
checkAndSendPendingRequest();
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 2ac2fef..6362dd7 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
@@ -30,7 +30,7 @@
*/
public class PublishProcessorState {
- private static final String LOG_TAG = "PublishProcessorState";
+ private static final String LOG_TAG = UceUtils.getLogPrefix() + "PublishProcessorState";
// The waiting period before the first retry.
private static final int RETRY_BASE_PERIOD = 1; // minute
@@ -129,7 +129,7 @@
// Adjust the timestamp to allow request PUBLISH with the specific delay time
private void adjustAllowedPublishTimestamp() {
synchronized (mLock) {
- Log.v(LOG_TAG, "adjustAllowedPublishTimestamp: retry=" + mRetryCount);
+ Log.d(LOG_TAG, "adjustAllowedPublishTimestamp: retry=" + mRetryCount);
if (mAllowedTimestamp == null) {
// Now for the initialization.
mAllowedTimestamp = Instant.now();
@@ -137,7 +137,7 @@
long nextRetryDuration = getNextRetryDuration();
mAllowedTimestamp = Instant.now().plus(Duration.ofMillis(nextRetryDuration));
}
- Log.v(LOG_TAG, "adjustAllowedPublishTimestamp: timestamp="
+ Log.d(LOG_TAG, "adjustAllowedPublishTimestamp: timestamp="
+ mAllowedTimestamp.toString());
}
}
@@ -145,11 +145,13 @@
// Return the milliseconds of the next retry delay.
private long getNextRetryDuration() {
synchronized (mLock) {
- int power = mRetryCount - 1;
- if (power < 0) {
- power = 0;
+ // If the current retry count is zero, the duration is also zero.
+ if (mRetryCount == 0) {
+ return 0L;
}
+
// Next retry duration (minute)
+ int power = mRetryCount - 1;
Double retryDuration = RETRY_BASE_PERIOD * Math.pow(2, power);
// Convert to millis
diff --git a/src/java/com/android/ims/rcs/uce/presence/publish/PublishRequestResponse.java b/src/java/com/android/ims/rcs/uce/presence/publish/PublishRequestResponse.java
index 33bdefc..b845826 100644
--- a/src/java/com/android/ims/rcs/uce/presence/publish/PublishRequestResponse.java
+++ b/src/java/com/android/ims/rcs/uce/presence/publish/PublishRequestResponse.java
@@ -16,6 +16,7 @@
package com.android.ims.rcs.uce.presence.publish;
+import android.annotation.Nullable;
import android.telephony.ims.RcsUceAdapter;
import android.telephony.ims.aidl.IPublishResponseCallback;
import android.telephony.ims.stub.RcsCapabilityExchangeImplBase;
@@ -23,6 +24,8 @@
import com.android.ims.rcs.uce.presence.publish.PublishController.PublishControllerCallback;
import com.android.ims.rcs.uce.util.NetworkSipCode;
+import java.time.Instant;
+
/**
* Receiving the result callback of the publish request.
*/
@@ -36,6 +39,9 @@
private int mNetworkRespSipCode;
private String mNetworkRespReason;
+ // The timestamp when receive the response from the network.
+ private Instant mResponseTimestamp;
+
public PublishRequestResponse(PublishControllerCallback publishCtrlCallback, long taskId) {
mTaskId = taskId;
mPublishCtrlCallback = publishCtrlCallback;
@@ -70,11 +76,16 @@
return mNetworkRespSipCode;
}
+ public @Nullable Instant getResponseTimestamp() {
+ return mResponseTimestamp;
+ }
+
public void onDestroy() {
mPublishCtrlCallback = null;
}
private void onCommandError(int errorCode) {
+ mResponseTimestamp = Instant.now();
mCmdErrorCode = errorCode;
updateRetryFlagByCommandError();
@@ -85,6 +96,7 @@
}
private void onNetworkResponse(int sipCode, String reason) {
+ mResponseTimestamp = Instant.now();
mNetworkRespSipCode = sipCode;
mNetworkRespReason = reason;
updateRetryFlagByNetworkResponse();
@@ -150,10 +162,14 @@
* Convert the network sip code to the publish state
*/
public int getPublishStateByNetworkResponse() {
- if (NetworkSipCode.SIP_CODE_REQUEST_TIMEOUT == mNetworkRespSipCode) {
- return RcsUceAdapter.PUBLISH_STATE_REQUEST_TIMEOUT;
+ switch (mNetworkRespSipCode) {
+ case NetworkSipCode.SIP_CODE_OK:
+ return RcsUceAdapter.PUBLISH_STATE_OK;
+ case NetworkSipCode.SIP_CODE_REQUEST_TIMEOUT:
+ return RcsUceAdapter.PUBLISH_STATE_REQUEST_TIMEOUT;
+ default:
+ return RcsUceAdapter.PUBLISH_STATE_OTHER_ERROR;
}
- return RcsUceAdapter.PUBLISH_STATE_OTHER_ERROR;
}
/**
@@ -163,9 +179,10 @@
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("taskId=").append(mTaskId)
- .append(", mCmdErrorCode=").append(mCmdErrorCode)
- .append(", onNetworkResponse=").append(mNetworkRespSipCode)
- .append(", mNetworkResponseReason=").append(mNetworkRespReason)
+ .append(", CmdErrorCode=").append(mCmdErrorCode)
+ .append(", NetworkResponse=").append(mNetworkRespSipCode)
+ .append(", NetworkResponseReason=").append(mNetworkRespReason)
+ .append(", ResponseTimestamp=").append(mResponseTimestamp)
.append(", isRequestSuccess=").append(isRequestSuccess())
.append(", needRetry=").append(mNeedRetry);
return builder.toString();
diff --git a/src/java/com/android/ims/rcs/uce/util/UceUtils.java b/src/java/com/android/ims/rcs/uce/util/UceUtils.java
index 37c0e30..1cc5104 100644
--- a/src/java/com/android/ims/rcs/uce/util/UceUtils.java
+++ b/src/java/com/android/ims/rcs/uce/util/UceUtils.java
@@ -25,11 +25,20 @@
public class UceUtils {
+ private static final String LOG_PREFIX = "RcsUce.";
+
private static final String LOG_TAG = "UceUtils";
private static long TASK_ID = 0L;
/**
+ * Get the log prefix of RCS UCE
+ */
+ public static String getLogPrefix() {
+ return LOG_PREFIX;
+ }
+
+ /**
* Generate the unique UCE request task id.
*/
public static synchronized long generateTaskId() {
diff --git a/tests/src/com/android/ims/rcs/uce/presence/publish/DeviceCapabilityListenerTest.java b/tests/src/com/android/ims/rcs/uce/presence/publish/DeviceCapabilityListenerTest.java
index 05085f8..16db1f1 100644
--- a/tests/src/com/android/ims/rcs/uce/presence/publish/DeviceCapabilityListenerTest.java
+++ b/tests/src/com/android/ims/rcs/uce/presence/publish/DeviceCapabilityListenerTest.java
@@ -144,7 +144,7 @@
verify(mDeviceCapability).updateImsMmtelRegistered(anyInt());
verify(mCallback).requestPublishFromInternal(
- PublishController.PUBLISH_TRIGGER_MMTEL_REGISTERED, 0L);
+ PublishController.PUBLISH_TRIGGER_MMTEL_REGISTERED, 500L);
}
@Test
@@ -171,7 +171,7 @@
verify(mDeviceCapability).updateImsRcsRegistered(anyInt());
verify(mCallback).requestPublishFromInternal(
- PublishController.PUBLISH_TRIGGER_RCS_REGISTERED, 0L);
+ PublishController.PUBLISH_TRIGGER_RCS_REGISTERED, 500L);
}
@Test
diff --git a/tests/src/com/android/ims/rcs/uce/presence/publish/PublishProcessorTest.java b/tests/src/com/android/ims/rcs/uce/presence/publish/PublishProcessorTest.java
index 68373df..c1e4de4 100644
--- a/tests/src/com/android/ims/rcs/uce/presence/publish/PublishProcessorTest.java
+++ b/tests/src/com/android/ims/rcs/uce/presence/publish/PublishProcessorTest.java
@@ -182,7 +182,7 @@
publishProcessor.onCommandError(mResponseCallback);
- verify(mPublishCtrlCallback).updatePublishRequestResult(anyInt());
+ verify(mPublishCtrlCallback).updatePublishRequestResult(anyInt(), any());
verify(mResponseCallback).onDestroy();
verify(mProcessorState).setPublishingFlag(false);
verify(mPublishCtrlCallback).clearRequestCanceledTimer();
@@ -219,7 +219,7 @@
publishProcessor.onNetworkResponse(mResponseCallback);
- verify(mPublishCtrlCallback).updatePublishRequestResult(anyInt());
+ verify(mPublishCtrlCallback).updatePublishRequestResult(anyInt(), any());
verify(mResponseCallback).onDestroy();
verify(mProcessorState).setPublishingFlag(false);
verify(mPublishCtrlCallback).clearRequestCanceledTimer();