summaryrefslogtreecommitdiff
path: root/rcs/rcsservice/src
diff options
context:
space:
mode:
authorBrad Ebinger <breadley@google.com>2019-12-19 15:14:40 -0800
committerBrad Ebinger <breadley@google.com>2020-01-08 15:47:02 -0800
commitc7771d8ad1479b3ca8b3ca2f5a085df0f5230359 (patch)
tree8e35a75f483088e12555195574a8812f7e761c0b /rcs/rcsservice/src
parent674766afb2abbe00a26a3265cbcb5d9d3a298263 (diff)
downloadims-c7771d8ad1479b3ca8b3ca2f5a085df0f5230359.tar.gz
Remove dependencies on library (2/2)
Moves all RcsService dependencies into app code and only leaves impl agnostic code in lib. One dependency left: RcsStackAdaptor should not be modifying tasks for resquestPublication, that should be done inside of PresencePublication because we need to move this code to Telephony. Test: Manual testing contact add/rm and verify vt status Change-Id: I4bef16c1e2aba257054b8d1208e82c5385bd4713
Diffstat (limited to 'rcs/rcsservice/src')
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/AlarmBroadcastReceiver.java (renamed from rcs/rcsservice/src/com/android/service/ims/presence/AlarmBroadcastReceiver.java)20
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/PresenceInfoParser.java (renamed from rcs/rcsservice/src/com/android/service/ims/presence/PresenceInfoParser.java)45
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/RcsService.java113
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/RcsSettingUtils.java327
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/RcsStackAdaptor.java126
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/RcsUtils.java28
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/StackListener.java (renamed from rcs/rcsservice/src/com/android/service/ims/presence/StackListener.java)117
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/Task.java22
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/TaskManager.java36
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/presence/ContactCapabilityResponse.java80
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/presence/PresenceAvailabilityTask.java3
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/presence/PresenceBase.java119
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/presence/PresenceCapabilityTask.java26
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/presence/PresencePublication.java333
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/presence/PresencePublishTask.java9
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/presence/PresencePublisher.java51
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/presence/PresenceSubscriber.java267
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/presence/PresenceTask.java16
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/presence/PresenceUtils.java71
-rw-r--r--rcs/rcsservice/src/com/android/service/ims/presence/SubscribePublisher.java53
20 files changed, 1132 insertions, 730 deletions
diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/AlarmBroadcastReceiver.java b/rcs/rcsservice/src/com/android/service/ims/AlarmBroadcastReceiver.java
index f191186..e06b4a4 100644
--- a/rcs/rcsservice/src/com/android/service/ims/presence/AlarmBroadcastReceiver.java
+++ b/rcs/rcsservice/src/com/android/service/ims/AlarmBroadcastReceiver.java
@@ -26,25 +26,19 @@
* DAMAGE.
*/
-package com.android.service.ims.presence;
+package com.android.service.ims;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.android.ims.internal.Logger;
-import com.android.service.ims.RcsStackAdaptor;
-import com.android.service.ims.TaskManager;
+import com.android.service.ims.presence.PresenceCapabilityTask;
+import com.android.service.ims.presence.PresencePublication;
public class AlarmBroadcastReceiver extends BroadcastReceiver{
private Logger logger = Logger.getLogger(this.getClass().getName());
- public static final String ACTION_RETRY_ALARM = "com.android.service.ims.presence.retry";
- private static final String ACTION_TASK_TIMEOUT_ALARM =
- PresenceCapabilityTask.ACTION_TASK_TIMEOUT_ALARM;
- private static final String ACTION_RETRY_PUBLISH_ALARM =
- PresencePublication.ACTION_RETRY_PUBLISH_ALARM;
-
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
@@ -58,15 +52,13 @@ public class AlarmBroadcastReceiver extends BroadcastReceiver{
return;
}
- if(ACTION_RETRY_ALARM.equals(action)) {
+ if(RcsStackAdaptor.ACTION_RETRY_ALARM.equals(action)) {
int times = intent.getIntExtra("times", -1);
rcsStackAdaptor.startInitThread(times);
- }else if(ACTION_TASK_TIMEOUT_ALARM.equals(action)){
+ }else if(PresenceCapabilityTask.ACTION_TASK_TIMEOUT_ALARM.equals(action)){
int taskId = intent.getIntExtra("taskId", -1);
TaskManager.getDefault().onTimeout(taskId);
- } else if(ACTION_RETRY_PUBLISH_ALARM.equals(action)) {
- // default retry is for 888
- int sipCode = intent.getIntExtra("sipCode", 888);
+ } else if(PresencePublication.ACTION_RETRY_PUBLISH_ALARM.equals(action)) {
PresencePublication publication = PresencePublication.getPresencePublication();
if(publication != null) {
publication.retryPublish();
diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceInfoParser.java b/rcs/rcsservice/src/com/android/service/ims/PresenceInfoParser.java
index 1b3d795..5edb9a1 100644
--- a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceInfoParser.java
+++ b/rcs/rcsservice/src/com/android/service/ims/PresenceInfoParser.java
@@ -26,7 +26,10 @@
* DAMAGE.
*/
-package com.android.service.ims.presence;
+package com.android.service.ims;
+
+import android.net.Uri;
+import android.telephony.ims.RcsContactUceCapability;
import java.lang.String;
import java.util.ArrayList;
@@ -39,6 +42,7 @@ import com.android.ims.internal.uce.presence.PresResInstanceInfo;
import com.android.ims.RcsPresenceInfo;
import com.android.ims.RcsPresenceInfo.ServiceType;
import com.android.ims.RcsPresenceInfo.ServiceState;
+import com.android.service.ims.presence.PresenceUtils;
public class PresenceInfoParser{
/*
@@ -166,8 +170,8 @@ public class PresenceInfoParser{
(ServiceState.ONLINE == presenceInfoTmp.getServiceState(
ServiceType.VT_CALL)))?ServiceState.ONLINE:
presenceInfoTmp.getServiceState(ServiceType.VT_CALL),
- presenceInfoTmp.getServiceContact(ServiceType.VOLTE_CALL),
- presenceInfoTmp.getTimeStamp(ServiceType.VOLTE_CALL)));
+ presenceInfoTmp.getServiceContact(ServiceType.VT_CALL),
+ presenceInfoTmp.getTimeStamp(ServiceType.VT_CALL)));
return;
}
}
@@ -268,4 +272,39 @@ public class PresenceInfoParser{
return number;
}
+
+ public static RcsContactUceCapability getUceCapability(RcsPresenceInfo info) {
+ RcsContactUceCapability.Builder result = new RcsContactUceCapability.Builder(
+ PresenceUtils.convertContactNumber(info.getContactNumber()));
+ if (ServiceState.ONLINE == info.getServiceState(ServiceType.VOLTE_CALL)) {
+ result.add(RcsContactUceCapability.CAPABILITY_IP_VOICE_CALL,
+ PresenceUtils.convertContactNumber(
+ info.getServiceContact(ServiceType.VOLTE_CALL)));
+ }
+ if (ServiceState.ONLINE == info.getServiceState(ServiceType.VT_CALL)) {
+ result.add(RcsContactUceCapability.CAPABILITY_IP_VIDEO_CALL,
+ PresenceUtils.convertContactNumber(
+ info.getServiceContact(ServiceType.VT_CALL)));
+ }
+ return result.build();
+ }
+
+ public static RcsPresenceInfo getRcsPresenceInfo(RcsContactUceCapability capability) {
+ int volteCapable = capability.isCapable(RcsContactUceCapability.CAPABILITY_IP_VOICE_CALL) ?
+ ServiceState.ONLINE : ServiceState.OFFLINE;
+ int vtCapable = capability.isCapable(RcsContactUceCapability.CAPABILITY_IP_VIDEO_CALL) ?
+ ServiceState.ONLINE : ServiceState.OFFLINE;
+ return new RcsPresenceInfo(capability.getContactUri().getSchemeSpecificPart(),
+ // Not sure what the difference is, just track voice capable.
+ (volteCapable == ServiceState.ONLINE) ? RcsPresenceInfo.VolteStatus.VOLTE_ENABLED :
+ RcsPresenceInfo.VolteStatus.VOLTE_DISABLED, volteCapable,
+ PresenceUtils.getNumber(capability.getServiceUri(
+ RcsContactUceCapability.CAPABILITY_IP_VOICE_CALL)),
+ // We always use system current time instead of time from server
+ System.currentTimeMillis(), vtCapable,
+ PresenceUtils.getNumber(capability.getServiceUri(
+ RcsContactUceCapability.CAPABILITY_IP_VIDEO_CALL)),
+ // We always use system current time instead of time from server
+ System.currentTimeMillis());
+ }
}
diff --git a/rcs/rcsservice/src/com/android/service/ims/RcsService.java b/rcs/rcsservice/src/com/android/service/ims/RcsService.java
index 78708da..f80e2e5 100644
--- a/rcs/rcsservice/src/com/android/service/ims/RcsService.java
+++ b/rcs/rcsservice/src/com/android/service/ims/RcsService.java
@@ -29,6 +29,7 @@
package com.android.service.ims;
import android.app.Service;
+import android.content.ComponentName;
import android.content.Intent;
import android.database.ContentObserver;
import android.net.ConnectivityManager;
@@ -44,20 +45,26 @@ import android.telephony.SubscriptionManager;
import android.telephony.ims.ImsException;
import android.telephony.ims.ImsMmTelManager;
import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.RcsContactUceCapability;
import android.telephony.ims.RegistrationManager;
import android.telephony.ims.feature.MmTelFeature;
import com.android.ims.IRcsPresenceListener;
-import com.android.ims.RcsManager.ResultCode;
+import com.android.ims.RcsPresenceInfo;
+import com.android.ims.ResultCode;
+import com.android.ims.RcsPresence;
import com.android.ims.internal.IRcsPresence;
import com.android.ims.internal.IRcsService;
import com.android.ims.internal.Logger;
-import com.android.internal.telephony.IccCardConstants;
import com.android.service.ims.R;
+import com.android.service.ims.presence.ContactCapabilityResponse;
+import com.android.service.ims.presence.PresenceBase;
import com.android.service.ims.presence.PresencePublication;
import com.android.service.ims.presence.PresenceSubscriber;
+import java.util.ArrayList;
import java.util.List;
+import java.util.stream.Collectors;
public class RcsService extends Service {
@@ -83,6 +90,78 @@ public class RcsService extends Service {
}
};
+ private class CapabilityResultListener implements ContactCapabilityResponse {
+
+ private final IRcsPresenceListener mListener;
+
+ public CapabilityResultListener(IRcsPresenceListener listener) {
+ mListener = listener;
+ }
+
+ @Override
+ public void onSuccess(int reqId) {
+ try {
+ mListener.onSuccess(reqId);
+ } catch (RemoteException e) {
+ logger.warn("CapabilityResultListener: onSuccess exception = " + e.getMessage());
+ }
+ }
+
+ @Override
+ public void onError(int reqId, int resultCode) {
+ try {
+ mListener.onError(reqId, resultCode);
+ } catch (RemoteException e) {
+ logger.warn("CapabilityResultListener: onError exception = " + e.getMessage());
+ }
+ }
+
+ @Override
+ public void onFinish(int reqId) {
+ try {
+ mListener.onFinish(reqId);
+ } catch (RemoteException e) {
+ logger.warn("CapabilityResultListener: onFinish exception = " + e.getMessage());
+ }
+ }
+
+ @Override
+ public void onTimeout(int reqId) {
+ try {
+ mListener.onTimeout(reqId);
+ } catch (RemoteException e) {
+ logger.warn("CapabilityResultListener: onTimeout exception = " + e.getMessage());
+ }
+ }
+
+ @Override
+ public void onCapabilitiesUpdated(List<RcsContactUceCapability> contactCapabilities,
+ boolean updateLastTimestamp) {
+ ArrayList<RcsPresenceInfo> presenceInfoList = contactCapabilities.stream().map(
+ PresenceInfoParser::getRcsPresenceInfo).collect(
+ Collectors.toCollection(ArrayList::new));
+
+ logger.debug("capabilities updated:");
+ for (RcsPresenceInfo info : presenceInfoList) {
+ logger.debug("capabilities updated: info -" + info);
+ }
+ // For some reason it uses an intent to send this info back instead of just using the
+ // active binder...
+ Intent intent = new Intent(RcsPresence.ACTION_PRESENCE_CHANGED);
+ intent.putParcelableArrayListExtra(RcsPresence.EXTRA_PRESENCE_INFO_LIST,
+ presenceInfoList);
+ intent.putExtra("updateLastTimestamp", updateLastTimestamp);
+ launchPersistService(intent);
+ }
+ }
+
+ private void launchPersistService(Intent intent) {
+ ComponentName component = new ComponentName("com.android.service.ims.presence",
+ "com.android.service.ims.presence.PersistService");
+ intent.setComponent(component);
+ startService(intent);
+ }
+
@Override
public void onCreate() {
super.onCreate();
@@ -266,7 +345,8 @@ public class RcsService extends Service {
return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
}
- return mSubscriber.requestCapability(contactsNumber, listener);
+ return mSubscriber.requestCapability(contactsNumber,
+ new CapabilityResultListener(listener));
}
/**
@@ -287,7 +367,8 @@ public class RcsService extends Service {
}
// check availability cache (in RAM).
- return mSubscriber.requestAvailability(contactNumber, listener, false);
+ return mSubscriber.requestAvailability(contactNumber,
+ new CapabilityResultListener(listener), false);
}
/**
@@ -309,11 +390,12 @@ public class RcsService extends Service {
}
// check availability cache (in RAM).
- return mSubscriber.requestAvailability(contactNumber, listener, true);
+ return mSubscriber.requestAvailability(contactNumber,
+ new CapabilityResultListener(listener), true);
}
public int getPublishState() throws RemoteException {
- return mPublication.getPublishState();
+ return publisherPublishStateToPublishState(mPublication.getPublishState());
}
};
@@ -448,5 +530,24 @@ public class RcsService extends Service {
mPublication.onFeatureCapabilityChanged(mNetworkRegistrationType, capabilities);
}
};
+
+ private static int publisherPublishStateToPublishState(int publisherPublishState) {
+ switch(publisherPublishState) {
+ case PresenceBase.PUBLISH_STATE_200_OK:
+ return RcsPresence.PublishState.PUBLISH_STATE_200_OK;
+ case PresenceBase.PUBLISH_STATE_NOT_PUBLISHED:
+ return RcsPresence.PublishState.PUBLISH_STATE_NOT_PUBLISHED;
+ case PresenceBase.PUBLISH_STATE_VOLTE_PROVISION_ERROR:
+ return RcsPresence.PublishState.PUBLISH_STATE_VOLTE_PROVISION_ERROR;
+ case PresenceBase.PUBLISH_STATE_RCS_PROVISION_ERROR:
+ return RcsPresence.PublishState.PUBLISH_STATE_RCS_PROVISION_ERROR;
+ case PresenceBase.PUBLISH_STATE_REQUEST_TIMEOUT:
+ return RcsPresence.PublishState.PUBLISH_STATE_REQUEST_TIMEOUT;
+ case PresenceBase.PUBLISH_STATE_OTHER_ERROR:
+ return RcsPresence.PublishState.PUBLISH_STATE_OTHER_ERROR;
+
+ }
+ return PresenceBase.PUBLISH_STATE_OTHER_ERROR;
+ }
}
diff --git a/rcs/rcsservice/src/com/android/service/ims/RcsSettingUtils.java b/rcs/rcsservice/src/com/android/service/ims/RcsSettingUtils.java
index 40fb709..f5f893e 100644
--- a/rcs/rcsservice/src/com/android/service/ims/RcsSettingUtils.java
+++ b/rcs/rcsservice/src/com/android/service/ims/RcsSettingUtils.java
@@ -31,82 +31,131 @@ package com.android.service.ims;
import android.content.Context;
import android.os.PersistableBundle;
import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.ims.ProvisioningManager;
+import android.telephony.ims.feature.MmTelFeature;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
-import com.android.ims.ImsConfig;
-import com.android.ims.ImsException;
-import com.android.ims.ImsManager;
import com.android.ims.internal.Logger;
-public class RcsSettingUtils{
- /*
- * The logger
- */
+import java.util.List;
+
+public class RcsSettingUtils {
static private Logger logger = Logger.getLogger("RcsSettingUtils");
- public RcsSettingUtils() {
+ // Values taken from ImsConfig - Should define in @SystemApi as well.
+ /**
+ * SIP T1 timer value in milliseconds. See RFC 3261 for definition.
+ * Value is in Integer format.
+ */
+ private static final int SIP_T1_TIMER = 7;
+ /**
+ * Whether or not capability discovery is provisioned.
+ */
+ private static final int CAPABILITY_DISCOVERY_ENABLED = 17;
+ /**
+ * period of time the availability information of a contact is cached on device.
+ * Value is in Integer format.
+ */
+ private static final int AVAILABILITY_CACHE_EXPIRATION = 19;
+ /**
+ * Minimum time between two published messages from the device.
+ * Value is in Integer format.
+ */
+ private static final int SOURCE_THROTTLE_PUBLISH = 21;
+ /**
+ * The Maximum number of MDNs contained in one Request Contained List.
+ * Value is in Integer format.
+ */
+ private static final int MAX_NUMENTRIES_IN_RCL = 22;
+ /**
+ * Expiration timer for subscription of a Request Contained List, used in capability
+ * polling.
+ * Value is in Integer format.
+ */
+ private static final int CAPAB_POLL_LIST_SUB_EXP = 23;
+ /**
+ * Provisioning status for Enhanced Address Book (EAB)
+ * Value is in Integer format.
+ */
+ private static final int EAB_SETTING_ENABLED = 25;
+ /**
+ * Whether or not mobile data is enabled currently.
+ */
+ private static final int MOBILE_DATA_ENABLED = 29;
+
+ public static boolean isVowifiProvisioned(Context context) {
+ try {
+ boolean isProvisioned;
+ ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(
+ getDefaultSubscriptionId(context));
+ isProvisioned = manager.getProvisioningStatusForCapability(
+ MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
+ ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN);
+ logger.debug("isVowifiProvisioned=" + isProvisioned);
+ return isProvisioned;
+ } catch (Exception e) {
+ logger.debug("isVowifiProvisioned, exception = " + e.getMessage());
+ return false;
+ }
}
- public static boolean isFeatureProvisioned(Context context,
- int featureId, boolean defaultValue) {
+ public static boolean isLvcProvisioned(Context context) {
+ try {
+ boolean isProvisioned;
+ ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(
+ getDefaultSubscriptionId(context));
+ isProvisioned = manager.getProvisioningStatusForCapability(
+ MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO,
+ ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
+ logger.debug("isLvcProvisioned=" + isProvisioned);
+ return isProvisioned;
+ } catch (Exception e) {
+ logger.debug("isLvcProvisioned, exception = " + e.getMessage());
+ return false;
+ }
+ }
+
+ public static boolean isEabProvisioned(Context context) {
+ boolean isProvisioned = false;
+ int subId = getDefaultSubscriptionId(context);
+ if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ logger.debug("isEabProvisioned: no valid subscriptions!");
+ return false;
+ }
CarrierConfigManager configManager = (CarrierConfigManager)
context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
- // Don't need provision.
if (configManager != null) {
- PersistableBundle config = configManager.getConfig();
+ PersistableBundle config = configManager.getConfigForSubId(subId);
if (config != null && !config.getBoolean(
CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONED_BOOL)) {
+ // If we don't need provisioning, just return true.
return true;
}
}
-
- boolean provisioned = defaultValue;
- ImsManager imsManager = ImsManager.getInstance(context, 0);
- if (imsManager != null) {
- try {
- ImsConfig imsConfig = imsManager.getConfigInterface();
- if (imsConfig != null) {
- provisioned = imsConfig.getProvisionedValue(featureId)
- == ImsConfig.FeatureValueConstants.ON;
- }
- } catch (ImsException ex) {
- }
+ try {
+ ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
+ isProvisioned = manager.getProvisioningIntValue(EAB_SETTING_ENABLED)
+ == ProvisioningManager.PROVISIONING_VALUE_ENABLED;
+ } catch (Exception e) {
+ logger.debug("isEabProvisioned: exception=" + e.getMessage());
}
-
- logger.debug("featureId=" + featureId + " provisioned=" + provisioned);
- return provisioned;
- }
-
- public static boolean isVowifiProvisioned(Context context) {
- return isFeatureProvisioned(context,
- ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED, false);
- }
-
- public static boolean isLvcProvisioned(Context context) {
- return isFeatureProvisioned(context,
- ImsConfig.ConfigConstants.LVC_SETTING_ENABLED, false);
- }
-
- public static boolean isEabProvisioned(Context context) {
- return isFeatureProvisioned(context,
- ImsConfig.ConfigConstants.EAB_SETTING_ENABLED, false);
+ logger.debug("isEabProvisioned=" + isProvisioned);
+ return isProvisioned;
}
public static int getSIPT1Timer(Context context) {
int sipT1Timer = 0;
-
- ImsManager imsManager = ImsManager.getInstance(context, 0);
- if (imsManager != null) {
- try {
- ImsConfig imsConfig = imsManager.getConfigInterface();
- if (imsConfig != null) {
- sipT1Timer = imsConfig.getProvisionedValue(
- ImsConfig.ConfigConstants.SIP_T1_TIMER);
- }
- } catch (ImsException ex) {
- }
+ try {
+ ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(
+ getDefaultSubscriptionId(context));
+ sipT1Timer = manager.getProvisioningIntValue(SIP_T1_TIMER);
+ } catch (Exception e) {
+ // If there is no active subscriptions, this will throw an exception.
+ logger.debug("getSIPT1Timer: exception=" + e.getMessage());
}
-
- logger.debug("sipT1Timer=" + sipT1Timer);
+ logger.debug("getSIPT1Timer=" + sipT1Timer);
return sipT1Timer;
}
@@ -115,20 +164,15 @@ public class RcsSettingUtils{
*/
public static boolean getCapabilityDiscoveryEnabled(Context context) {
boolean capabilityDiscoveryEnabled = false;
-
- ImsManager imsManager = ImsManager.getInstance(context, 0);
- if (imsManager != null) {
- try {
- ImsConfig imsConfig = imsManager.getConfigInterface();
- if (imsConfig != null) {
- capabilityDiscoveryEnabled = imsConfig.getProvisionedValue(
- ImsConfig.ConfigConstants.CAPABILITY_DISCOVERY_ENABLED)
- == ImsConfig.FeatureValueConstants.ON;
- }
- } catch (ImsException ex) {
- }
+ try {
+ ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(
+ getDefaultSubscriptionId(context));
+ capabilityDiscoveryEnabled = manager.getProvisioningIntValue(CAPABILITY_DISCOVERY_ENABLED)
+ == ProvisioningManager.PROVISIONING_VALUE_ENABLED;
+ } catch (Exception e) {
+ // If there is no active subscriptions, this will throw an exception.
+ logger.debug("capabilityDiscoveryEnabled: exception=" + e.getMessage());
}
-
logger.debug("capabilityDiscoveryEnabled=" + capabilityDiscoveryEnabled);
return capabilityDiscoveryEnabled;
}
@@ -138,20 +182,15 @@ public class RcsSettingUtils{
*/
public static int getMaxNumbersInRCL(Context context) {
int maxNumbersInRCL = 100;
-
- ImsManager imsManager = ImsManager.getInstance(context, 0);
- if (imsManager != null) {
- try {
- ImsConfig imsConfig = imsManager.getConfigInterface();
- if (imsConfig != null) {
- maxNumbersInRCL = imsConfig.getProvisionedValue(
- ImsConfig.ConfigConstants.MAX_NUMENTRIES_IN_RCL);
- }
- } catch (ImsException ex) {
- }
+ try {
+ ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(
+ getDefaultSubscriptionId(context));
+ maxNumbersInRCL = manager.getProvisioningIntValue(MAX_NUMENTRIES_IN_RCL);
+ } catch (Exception e) {
+ // If there is no active subscriptions, this will throw an exception.
+ logger.debug("getMaxNumbersInRCL: exception=" + e.getMessage());
}
-
- logger.debug("maxNumbersInRCL=" + maxNumbersInRCL);
+ logger.debug("getMaxNumbersInRCL=" + maxNumbersInRCL);
return maxNumbersInRCL;
}
@@ -160,98 +199,100 @@ public class RcsSettingUtils{
*/
public static int getCapabPollListSubExp(Context context) {
int capabPollListSubExp = 30;
-
- ImsManager imsManager = ImsManager.getInstance(context, 0);
- if (imsManager != null) {
- try {
- ImsConfig imsConfig = imsManager.getConfigInterface();
- if (imsConfig != null) {
- capabPollListSubExp = imsConfig.getProvisionedValue(
- ImsConfig.ConfigConstants.CAPAB_POLL_LIST_SUB_EXP);
- }
- } catch (ImsException ex) {
- }
+ try {
+ ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(
+ getDefaultSubscriptionId(context));
+ capabPollListSubExp = manager.getProvisioningIntValue(CAPAB_POLL_LIST_SUB_EXP);
+ } catch (Exception e) {
+ // If there is no active subscriptions, this will throw an exception.
+ logger.debug("getCapabPollListSubExp: exception=" + e.getMessage());
}
-
- logger.debug("capabPollListSubExp=" + capabPollListSubExp);
+ logger.debug("getCapabPollListSubExp=" + capabPollListSubExp);
return capabPollListSubExp;
}
/**
- * Peiod of time the availability information of a contact is cached on device.
+ * Period of time the availability information of a contact is cached on device.
*/
public static int getAvailabilityCacheExpiration(Context context) {
int availabilityCacheExpiration = 30;
-
- ImsManager imsManager = ImsManager.getInstance(context, 0);
- if (imsManager != null) {
- try {
- ImsConfig imsConfig = imsManager.getConfigInterface();
- if (imsConfig != null) {
- availabilityCacheExpiration = imsConfig.getProvisionedValue(
- ImsConfig.ConfigConstants.AVAILABILITY_CACHE_EXPIRATION);
- }
- } catch (ImsException ex) {
- }
+ try {
+ ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(
+ getDefaultSubscriptionId(context));
+ availabilityCacheExpiration = manager.getProvisioningIntValue(
+ AVAILABILITY_CACHE_EXPIRATION);
+ } catch (Exception e) {
+ // If there is no active subscriptions, this will throw an exception.
+ logger.debug("getAvailabilityCacheExpiration: exception=" + e.getMessage());
}
-
- logger.debug("availabilityCacheExpiration=" + availabilityCacheExpiration);
+ logger.debug("getAvailabilityCacheExpiration=" + availabilityCacheExpiration);
return availabilityCacheExpiration;
}
public static boolean isMobileDataEnabled(Context context) {
boolean mobileDataEnabled = false;
- ImsManager imsManager = ImsManager.getInstance(context, 0);
- if (imsManager != null) {
- try {
- ImsConfig imsConfig = imsManager.getConfigInterface();
- if (imsConfig != null) {
- mobileDataEnabled = imsConfig.getProvisionedValue(
- ImsConfig.ConfigConstants.MOBILE_DATA_ENABLED)
- == ImsConfig.FeatureValueConstants.ON;
- }
- } catch (ImsException ex) {
- }
+ try {
+ ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(
+ getDefaultSubscriptionId(context));
+ mobileDataEnabled = manager.getProvisioningIntValue(MOBILE_DATA_ENABLED)
+ == ProvisioningManager.PROVISIONING_VALUE_ENABLED;
+ } catch (Exception e) {
+ // If there is no active subscriptions, this will throw an exception.
+ logger.debug("isMobileDataEnabled: exception=" + e.getMessage());
}
-
logger.debug("mobileDataEnabled=" + mobileDataEnabled);
return mobileDataEnabled;
}
public static void setMobileDataEnabled(Context context, boolean mobileDataEnabled) {
logger.debug("mobileDataEnabled=" + mobileDataEnabled);
- ImsManager imsManager = ImsManager.getInstance(context, 0);
- if (imsManager != null) {
- try {
- ImsConfig imsConfig = imsManager.getConfigInterface();
- if (imsConfig != null) {
- imsConfig.setProvisionedValue(
- ImsConfig.ConfigConstants.MOBILE_DATA_ENABLED, mobileDataEnabled?
- ImsConfig.FeatureValueConstants.ON:ImsConfig.FeatureValueConstants.OFF);
- }
- } catch (ImsException ex) {
- logger.debug("ImsException", ex);
- }
+ try {
+ ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(
+ getDefaultSubscriptionId(context));
+ manager.setProvisioningIntValue(MOBILE_DATA_ENABLED, mobileDataEnabled ?
+ ProvisioningManager.PROVISIONING_VALUE_ENABLED :
+ ProvisioningManager.PROVISIONING_VALUE_DISABLED);
+ } catch (Exception e) {
+ // If there is no active subscriptions, this will throw an exception.
+ logger.debug("mobileDataEnabled: exception=" + e.getMessage());
}
}
public static int getPublishThrottle(Context context) {
+ // Default
int publishThrottle = 60000;
+ try {
+ ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(
+ getDefaultSubscriptionId(context));
+ publishThrottle = manager.getProvisioningIntValue(SOURCE_THROTTLE_PUBLISH);
+ } catch (Exception e) {
+ // If there is no active subscriptions, this will throw an exception.
+ logger.debug("publishThrottle: exception=" + e.getMessage());
+ }
+ logger.debug("publishThrottle=" + publishThrottle);
+ return publishThrottle;
+ }
- ImsManager imsManager = ImsManager.getInstance(context, 0);
- if (imsManager != null) {
- try {
- ImsConfig imsConfig = imsManager.getConfigInterface();
- if (imsConfig != null) {
- publishThrottle = imsConfig.getProvisionedValue(
- ImsConfig.ConfigConstants.SOURCE_THROTTLE_PUBLISH);
+ private static int getDefaultSubscriptionId(Context context) {
+ SubscriptionManager sm = context.getSystemService(SubscriptionManager.class);
+ List<SubscriptionInfo> infos = sm.getActiveSubscriptionInfoList();
+ if (infos == null || infos.isEmpty()) {
+ // There are no active subscriptions right now.
+ return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ }
+ // This code does not support MSIM unfortunately, so only provide presence on the default
+ // subscription that the user chose.
+ int defaultSub = SubscriptionManager.getDefaultSubscriptionId();
+ // If the user has no default set, just pick the first as backup.
+ if (defaultSub == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ for (SubscriptionInfo info : infos) {
+ if (!info.isOpportunistic()) {
+ defaultSub = info.getSubscriptionId();
+ break;
}
- } catch (ImsException ex) {
}
}
-
- logger.debug("publishThrottle=" + publishThrottle);
- return publishThrottle;
+ return defaultSub;
}
}
diff --git a/rcs/rcsservice/src/com/android/service/ims/RcsStackAdaptor.java b/rcs/rcsservice/src/com/android/service/ims/RcsStackAdaptor.java
index eb2edd7..4f1df37 100644
--- a/rcs/rcsservice/src/com/android/service/ims/RcsStackAdaptor.java
+++ b/rcs/rcsservice/src/com/android/service/ims/RcsStackAdaptor.java
@@ -44,12 +44,11 @@ import android.os.SystemClock;
import android.os.SystemProperties;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.telephony.ims.RcsContactUceCapability;
+import android.text.TextUtils;
-import com.android.ims.IRcsPresenceListener;
-import com.android.ims.RcsManager.ResultCode;
+import com.android.ims.ResultCode;
import com.android.ims.RcsPresence;
-import com.android.ims.RcsPresence.PublishState;
-import com.android.ims.RcsPresenceInfo;
import com.android.ims.internal.ContactNumberUtils;
import com.android.ims.internal.Logger;
import com.android.ims.internal.uce.common.CapInfo;
@@ -59,18 +58,23 @@ import com.android.ims.internal.uce.presence.IPresenceService;
import com.android.ims.internal.uce.presence.PresCapInfo;
import com.android.ims.internal.uce.uceservice.IUceService;
import com.android.ims.internal.uce.uceservice.ImsUceManager;
-import com.android.service.ims.presence.AlarmBroadcastReceiver;
-import com.android.service.ims.presence.PresenceInfoParser;
-import com.android.service.ims.presence.PresencePublication;
-import com.android.service.ims.presence.StackListener;
+import com.android.service.ims.presence.PresenceBase;
+import com.android.service.ims.presence.PresencePublisher;
+import com.android.service.ims.presence.SubscribePublisher;
-public class RcsStackAdaptor{
+public class RcsStackAdaptor implements PresencePublisher, SubscribePublisher {
private static final boolean DEBUG = true;
private static final String PERSIST_SERVICE_NAME =
"com.android.service.ims.presence.PersistService";
private static final String PERSIST_SERVICE_PACKAGE = "com.android.service.ims.presence";
+ /**
+ * PendingIntent action used to retry getting the UCE service. Need an associated
+ * BroadcastReceiver.
+ */
+ public static final String ACTION_RETRY_ALARM = "com.android.service.ims.presence.retry";
+
// The logger
private Logger logger = Logger.getLogger(this.getClass().getName());
@@ -83,7 +87,7 @@ public class RcsStackAdaptor{
// provision status can be set by both subscribe and pubilish
// for unprovisioned for 403 or 404
- private volatile int mPublishingState = PublishState.PUBLISH_STATE_NOT_PUBLISHED;
+ private volatile int mPublishingState = PresenceBase.PUBLISH_STATE_NOT_PUBLISHED;
// It is initializing the stack presence service.
private volatile boolean mIsIniting = false;
@@ -186,7 +190,8 @@ public class RcsStackAdaptor{
return mListenerHandler;
}
- public int checkStackAndPublish(){
+ @Override
+ public int getStackStatusForCapabilityRequest() {
if (!RcsSettingUtils.getCapabilityDiscoveryEnabled(mContext)) {
logger.error("getCapabilityDiscoveryEnabled = false");
return ResultCode.ERROR_SERVICE_NOT_ENABLED;
@@ -199,16 +204,15 @@ public class RcsStackAdaptor{
}
if (!isPublished()) {
- logger.error(
- "checkStackAndPublish ERROR_SERVICE_NOT_PUBLISHED");
+ logger.error("checkStackAndPublish ERROR_SERVICE_NOT_PUBLISHED");
return ResultCode.ERROR_SERVICE_NOT_PUBLISHED;
}
return ResultCode.SUCCESS;
}
- private boolean isPublished(){
- if(getPublishState() != PublishState.PUBLISH_STATE_200_OK){
+ private boolean isPublished() {
+ if (getPublisherState() != PresenceBase.PUBLISH_STATE_200_OK) {
logger.error("Didnt' publish properly");
return false;
}
@@ -216,33 +220,30 @@ public class RcsStackAdaptor{
return true;
}
- public void setPublishState(int publishState) {
+ @Override
+ public void updatePublisherState(@PresenceBase.PresencePublishState int publishState) {
synchronized (mSyncObj) {
logger.print("mPublishingState=" + mPublishingState + " publishState=" + publishState);
- if (mPublishingState != publishState) {
- // save it for recovery when PresenceService crash.
- SystemProperties.set("rcs.publish.status",
- String.valueOf(publishState));
-
- Intent publishIntent = new Intent(RcsPresence.ACTION_PUBLISH_STATE_CHANGED);
- publishIntent.putExtra(RcsPresence.EXTRA_PUBLISH_STATE, publishState);
- // Start PersistService and broadcast to other receivers that are listening
- // dynamically.
- mContext.sendStickyBroadcast(publishIntent);
- launchPersistService(publishIntent);
- }
-
mPublishingState = publishState;
}
+ // save it for recovery when PresenceService crash.
+ SystemProperties.set("rcs.publish.status", String.valueOf(publishState));
+ Intent publishIntent = new Intent(RcsPresence.ACTION_PUBLISH_STATE_CHANGED);
+ publishIntent.putExtra(RcsPresence.EXTRA_PUBLISH_STATE, publishState);
+ // Start PersistService and broadcast to other receivers that are listening
+ // dynamically.
+ mContext.sendStickyBroadcast(publishIntent);
+ launchPersistService(publishIntent);
}
- public int getPublishState(){
+ @Override
+ public @PresenceBase.PresencePublishState int getPublisherState() {
synchronized (mSyncObj) {
return mPublishingState;
}
}
- public int checkStackStatus(){
+ private int checkStackStatus() {
synchronized (mSyncObj) {
if (!RcsSettingUtils.isEabProvisioned(mContext)) {
logger.error("Didn't get EAB provisioned by DM");
@@ -275,19 +276,20 @@ public class RcsStackAdaptor{
return ResultCode.SUCCESS;
}
- public int requestCapability(String[] formatedContacts, int taskId){
- logger.print("requestCapability formatedContacts=" + formatedContacts);
+ @Override
+ public int requestCapability(String[] formattedContacts, int taskId) {
+ logger.print("requestCapability formattedContacts=" + formattedContacts);
int ret = ResultCode.SUCCESS;
try {
synchronized (mSyncObj) {
StatusCode retCode;
- if (formatedContacts.length == 1) {
+ if (formattedContacts.length == 1) {
retCode = mStackPresService.getContactCap(
- mStackPresenceServiceHandle, formatedContacts[0], taskId);
+ mStackPresenceServiceHandle, formattedContacts[0], taskId);
} else {
retCode = mStackPresService.getContactListCap(
- mStackPresenceServiceHandle, formatedContacts, taskId);
+ mStackPresenceServiceHandle, formattedContacts, taskId);
}
logger.print("GetContactListCap retCode=" + retCode);
@@ -304,14 +306,15 @@ public class RcsStackAdaptor{
return ret;
}
- public int requestAvailability(String formatedContact, int taskId){
+ @Override
+ public int requestAvailability(String formattedContact, int taskId) {
logger.debug("requestAvailability ...");
int ret = ResultCode.SUCCESS;
try{
synchronized (mSyncObj) {
StatusCode retCode = mStackPresService.getContactCap(
- mStackPresenceServiceHandle, formatedContact, taskId);
+ mStackPresenceServiceHandle, formattedContact, taskId);
logger.print("getContactCap retCode=" + retCode);
ret = RcsUtils.statusCodeToResultCode(retCode.getStatusCode());
@@ -325,7 +328,8 @@ public class RcsStackAdaptor{
return ret;
}
- public int requestPublication(RcsPresenceInfo presenceInfo, IRcsPresenceListener listener) {
+ @Override
+ public int requestPublication(RcsContactUceCapability capabilities) {
logger.debug("requestPublication ...");
// Don't use checkStackAndPublish()
@@ -338,15 +342,15 @@ public class RcsStackAdaptor{
TelephonyManager teleMgr = (TelephonyManager) mContext.getSystemService(
Context.TELEPHONY_SERVICE);
- if(teleMgr == null){
+ if (teleMgr == null) {
logger.error("teleMgr = null");
- return PresencePublication.PUBLISH_GENIRIC_FAILURE;
+ return ResultCode.PUBLISH_GENERIC_FAILURE;
}
String myNumUri = null;
String myDomain = teleMgr.getIsimDomain();
logger.debug("myDomain=" + myDomain);
- if(myDomain != null && myDomain.length() !=0){
+ if (myDomain != null && !TextUtils.isEmpty(myDomain)) {
String[] impu = teleMgr.getIsimImpu();
if(impu !=null){
@@ -363,34 +367,32 @@ public class RcsStackAdaptor{
String myNumber = PresenceInfoParser.getPhoneFromUri(myNumUri);
- if(myNumber == null){
+ if (myNumber == null) {
myNumber = ContactNumberUtils.getDefault().format(teleMgr.getLine1Number());
- if(myDomain != null && myDomain.length() !=0){
+ if (myDomain != null && !TextUtils.isEmpty(myDomain)) {
myNumUri = "sip:" + myNumber + "@" + myDomain;
- }else{
+ } else {
myNumUri = "tel:" + myNumber;
}
}
logger.print("myNumUri=" + myNumUri + " myNumber=" + myNumber);
- if(myNumUri == null || myNumber == null){
+ if (myNumUri == null || myNumber == null) {
logger.error("Didn't find number or impu.");
- return PresencePublication.PUBLISH_GENIRIC_FAILURE;
+ return ResultCode.PUBLISH_GENERIC_FAILURE;
}
- int taskId = TaskManager.getDefault().addPublishTask(myNumber, listener);
- try{
+ int taskId = TaskManager.getDefault().addPublishTask(myNumber);
+ try {
PresCapInfo pMyCapInfo = new PresCapInfo();
// Fill cap info
pMyCapInfo.setContactUri(myNumUri);
CapInfo capInfo = new CapInfo();
- capInfo.setIpVoiceSupported(presenceInfo.getServiceState(
- RcsPresenceInfo.ServiceType.VOLTE_CALL)
- == RcsPresenceInfo.ServiceState.ONLINE);
- capInfo.setIpVideoSupported(presenceInfo.getServiceState(
- RcsPresenceInfo.ServiceType.VT_CALL)
- == RcsPresenceInfo.ServiceState.ONLINE);
+ capInfo.setIpVoiceSupported(capabilities.isCapable(
+ RcsContactUceCapability.CAPABILITY_IP_VIDEO_CALL));
+ capInfo.setIpVideoSupported(capabilities.isCapable(
+ RcsContactUceCapability.CAPABILITY_IP_VIDEO_CALL));
capInfo.setCdViaPresenceSupported(true);
capInfo.setFtSupported(false); // TODO: support FT
@@ -413,12 +415,12 @@ public class RcsStackAdaptor{
}
logger.debug("requestPublication ret=" + ret);
- if(ret != ResultCode.SUCCESS){
+ if (ret != ResultCode.SUCCESS) {
logger.error("requestPublication remove taskId=" + taskId);
TaskManager.getDefault().removeTask(taskId);
return ret;
}
- }catch(RemoteException e){
+ } catch (RemoteException e) {
e.printStackTrace();
logger.error("Exception when call mStackPresService.getContactCap");
logger.error("requestPublication remove taskId=" + taskId);
@@ -608,6 +610,12 @@ public class RcsStackAdaptor{
initImsUceService();
setInPowerDown(false);
+ try {
+ // Restore the previous value in case the process has crashed.
+ updatePublisherState(Integer.parseInt(SystemProperties.get("rcs.publish.status", "1")));
+ } catch (NumberFormatException e) {
+ // do nothing and use the default.
+ }
logger.debug("init finished");
}
@@ -626,9 +634,9 @@ public class RcsStackAdaptor{
mIsIniting = true;
- Intent intent = new Intent(AlarmBroadcastReceiver.ACTION_RETRY_ALARM);
+ Intent intent = new Intent(ACTION_RETRY_ALARM);
intent.putExtra("times", times);
- intent.setClass(mContext, AlarmBroadcastReceiver.class);
+ intent.setPackage(mContext.getPackageName());
mRetryAlarmIntent = PendingIntent.getBroadcast(mContext, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
diff --git a/rcs/rcsservice/src/com/android/service/ims/RcsUtils.java b/rcs/rcsservice/src/com/android/service/ims/RcsUtils.java
index 22e156e..0e05e7f 100644
--- a/rcs/rcsservice/src/com/android/service/ims/RcsUtils.java
+++ b/rcs/rcsservice/src/com/android/service/ims/RcsUtils.java
@@ -28,18 +28,10 @@
package com.android.service.ims;
-import com.android.ims.RcsManager.ResultCode;
-import com.android.ims.internal.Logger;
+import com.android.ims.ResultCode;
import com.android.ims.internal.uce.common.StatusCode;
-public class RcsUtils{
- /*
- * The logger
- */
- static private Logger logger = Logger.getLogger("RcsUtils");
-
- public RcsUtils() {
- }
+public class RcsUtils {
static public int statusCodeToResultCode(int sipStatusCode){
if(sipStatusCode == StatusCode.UCE_SUCCESS ||
@@ -83,21 +75,5 @@ public class RcsUtils{
return ResultCode.SUBSCRIBE_GENERIC;
}
-
- static public String toContactString(String[] contacts) {
- if(contacts == null) {
- return null;
- }
-
- String result = "";
- for(int i=0; i<contacts.length; i++) {
- result += contacts[i];
- if(i != contacts.length -1) {
- result += ";";
- }
- }
-
- return result;
- }
}
diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/StackListener.java b/rcs/rcsservice/src/com/android/service/ims/StackListener.java
index ae1d415..7edf080 100644
--- a/rcs/rcsservice/src/com/android/service/ims/presence/StackListener.java
+++ b/rcs/rcsservice/src/com/android/service/ims/StackListener.java
@@ -26,7 +26,7 @@
* DAMAGE.
*/
-package com.android.service.ims.presence;
+package com.android.service.ims;
import android.content.Context;
import android.content.Intent;
@@ -35,9 +35,12 @@ import android.os.Looper;
import android.os.Message;
import android.os.Parcel;
import android.os.RemoteException;
+import android.telephony.ims.RcsContactUceCapability;
+import android.text.TextUtils;
import android.util.Log;
import com.android.ims.RcsManager;
+import com.android.ims.RcsPresenceInfo;
import com.android.ims.internal.Logger;
import com.android.ims.internal.uce.common.StatusCode;
import com.android.ims.internal.uce.presence.IPresenceListener;
@@ -47,8 +50,12 @@ import com.android.ims.internal.uce.presence.PresPublishTriggerType;
import com.android.ims.internal.uce.presence.PresResInfo;
import com.android.ims.internal.uce.presence.PresRlmiInfo;
import com.android.ims.internal.uce.presence.PresSipResponse;
+import com.android.ims.internal.uce.presence.PresSubscriptionState;
import com.android.ims.internal.uce.presence.PresTupleInfo;
-import com.android.service.ims.RcsStackAdaptor;
+import com.android.service.ims.presence.PresencePublication;
+import com.android.service.ims.presence.PresenceSubscriber;
+
+import java.util.ArrayList;
public class StackListener extends Handler{
/*
@@ -82,7 +89,7 @@ public class StackListener extends Handler{
mContext = context;
}
- public void setPresencePublication(PresencePublication presencePublication){
+ public void setPresencePublication(PresencePublication presencePublication) {
mPresencePublication = presencePublication;
}
@@ -111,7 +118,8 @@ public class StackListener extends Handler{
return;
}
- mPresencePublication.invokePublish(val);
+ mPresencePublication.onStackPublishRequested(
+ convertToStackPublishTriggerType(val.getPublishTrigeerType()));
break;
}
@@ -119,13 +127,16 @@ public class StackListener extends Handler{
case PRESENCE_IMS_UNSOL_PUBLISH_CMDSTATUS:
{
PresCmdStatus pCmdStatus = (PresCmdStatus) msg.obj;
- if(mPresencePublication == null || pCmdStatus == null){
+ if(mPresencePublication == null || pCmdStatus == null) {
logger.error("mPresencePublication=" + mPresencePublication +
" pCmdStatus=" + pCmdStatus);
return;
}
- mPresencePublication.handleCmdStatus(pCmdStatus);
+ int commandResult = RcsUtils.statusCodeToResultCode(
+ pCmdStatus.getStatus().getStatusCode());
+ mPresencePublication.onCommandStatusUpdated(pCmdStatus.getUserData(),
+ pCmdStatus.getRequestId(), commandResult);
}
break;
@@ -138,8 +149,10 @@ public class StackListener extends Handler{
" pCmdStatus=" + pCmdStatus);
return;
}
-
- mPresenceSubscriber.handleCmdStatus(pCmdStatus);
+ int commandResult = RcsUtils.statusCodeToResultCode(
+ pCmdStatus.getStatus().getStatusCode());
+ mPresenceSubscriber.onCommandStatusUpdated(pCmdStatus.getUserData(),
+ pCmdStatus.getRequestId(), commandResult);
break;
}
@@ -147,13 +160,14 @@ public class StackListener extends Handler{
case PRESENCE_IMS_UNSOL_PUBLISH_SIPRESPONSE:
{
PresSipResponse pSipResponse = (PresSipResponse) msg.obj;
- if(mPresencePublication == null || pSipResponse == null){
+ if(mPresencePublication == null || pSipResponse == null) {
logger.error("mPresencePublication=" + mPresencePublication +
"pSipResponse=" +pSipResponse);
return;
}
- mPresencePublication.handleSipResponse(pSipResponse);
+ mPresencePublication.onSipResponse(pSipResponse.getRequestId(),
+ pSipResponse.getSipResponseCode(), pSipResponse.getReasonPhrase());
break;
}
@@ -167,7 +181,8 @@ public class StackListener extends Handler{
return;
}
- mPresenceSubscriber.handleSipResponse(pSipResponse);
+ mPresenceSubscriber.onSipResponse(pSipResponse.getRequestId(),
+ pSipResponse.getSipResponseCode(), pSipResponse.getReasonPhrase());
break;
}
@@ -180,9 +195,16 @@ public class StackListener extends Handler{
" notifyData=" + notifyData);
return;
}
-
- mPresenceSubscriber.updatePresence(notifyData.getUri(),
- notifyData.getTupleInfo());
+ RcsPresenceInfo rcsPresenceInfo = PresenceInfoParser.getPresenceInfoFromTuple(
+ notifyData.getUri(), notifyData.getTupleInfo());
+ if(rcsPresenceInfo == null || TextUtils.isEmpty(
+ rcsPresenceInfo.getContactNumber())){
+ logger.error("rcsPresenceInfo is null or " +
+ "TextUtils.isEmpty(rcsPresenceInfo.getContactNumber()");
+ return;
+ }
+ mPresenceSubscriber.updatePresence(
+ PresenceInfoParser.getUceCapability(rcsPresenceInfo));
break;
}
@@ -196,8 +218,40 @@ public class StackListener extends Handler{
return;
}
- mPresenceSubscriber.updatePresences(notifyListData.getRlmiInfo(),
- notifyListData.getResInfo());
+ RcsPresenceInfo[] rcsPresenceInfos = PresenceInfoParser.
+ getPresenceInfosFromPresenceRes(notifyListData.getRlmiInfo(),
+ notifyListData.getResInfo());
+ if(rcsPresenceInfos == null){
+ logger.error("updatePresences: rcsPresenceInfos == null");
+ return;
+ }
+
+ PresRlmiInfo info = notifyListData.getRlmiInfo();
+ boolean isTerminated = false;
+ if (info.getPresSubscriptionState() != null) {
+ if (info.getPresSubscriptionState().getPresSubscriptionStateValue() ==
+ PresSubscriptionState.UCE_PRES_SUBSCRIPTION_STATE_TERMINATED) {
+ isTerminated = true;
+ }
+ }
+
+ ArrayList<RcsContactUceCapability> capabilities = new ArrayList<>();
+
+ for (int i=0; i < rcsPresenceInfos.length; i++) {
+ if(rcsPresenceInfos[i] != null && TextUtils.isEmpty(
+ rcsPresenceInfos[i].getContactNumber())){
+ continue;
+ }
+ RcsContactUceCapability capability = PresenceInfoParser.getUceCapability(
+ rcsPresenceInfos[i]);
+ if(capability != null && (capability.getContactUri() != null)){
+ logger.debug("capability=" + capability);
+ capabilities.add(capability);
+ }
+ }
+
+ mPresenceSubscriber.updatePresences(info.getRequestId(), capabilities, isTerminated,
+ info.getSubscriptionTerminatedReason());
break;
}
@@ -353,11 +407,9 @@ public class StackListener extends Handler{
}
// Handle the cached trigger which got from stack
- if(mPresencePublication != null && mPresencePublication.getHasCachedTrigger()){
+ if(mPresencePublication != null) {
logger.debug("publish for cached trigger");
-
- mPresencePublication.invokePublish(
- PresencePublication.PublishType.PRES_PUBLISH_TRIGGER_CACHED_TRIGGER);
+ mPresencePublication.onStackAvailable();
}
Intent intent = new Intent(RcsManager.ACTION_RCS_SERVICE_AVAILABLE);
@@ -518,5 +570,30 @@ public class StackListener extends Handler{
logger.debug("unpublishMessageSent()");
}
};
+
+ @PresencePublication.StackPublishTriggerType
+ private static int convertToStackPublishTriggerType(int presPublishTriggerType) {
+ switch (presPublishTriggerType) {
+ case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_ETAG_EXPIRED:
+ return PresencePublication.UCE_PRES_PUBLISH_TRIGGER_ETAG_EXPIRED;
+ case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED:
+ return PresencePublication.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED;
+ case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED:
+ return PresencePublication.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED;
+ case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_EHRPD:
+ return PresencePublication.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_EHRPD;
+ case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_HSPAPLUS:
+ return PresencePublication.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_HSPAPLUS;
+ case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_3G:
+ return PresencePublication.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_3G;
+ case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_2G:
+ return PresencePublication.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_2G;
+ case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_WLAN:
+ return PresencePublication.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_WLAN;
+ case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_IWLAN:
+ return PresencePublication.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_IWLAN;
+ }
+ return PresencePublication.UCE_PRES_PUBLISH_TRIGGER_UNKNOWN;
+ }
}
diff --git a/rcs/rcsservice/src/com/android/service/ims/Task.java b/rcs/rcsservice/src/com/android/service/ims/Task.java
index eb36a5f..61e85b4 100644
--- a/rcs/rcsservice/src/com/android/service/ims/Task.java
+++ b/rcs/rcsservice/src/com/android/service/ims/Task.java
@@ -28,8 +28,8 @@
package com.android.service.ims;
-import com.android.ims.IRcsPresenceListener;
import com.android.ims.internal.Logger;
+import com.android.service.ims.presence.ContactCapabilityResponse;
/**
* Task
@@ -51,21 +51,6 @@ public class Task{
// QRCS_PRES_CMD_SETNEWFEATURETAG
public int mCmdId;
- // filled after IQPresListener_CMDStatus
- // QRCS_STATUSCODE, possible values are:
- // QRCS_SUCCESS
- // QRCS_FAILURE
- // QRCS_SUCCESS_ASYC_UPDATE
- // QRCS_INVALID_SERVICE_HANDLE
- // QRCS_INVALID_LISTENER_HANDLE
- // QRCS_INVALID_PARAM
- // QRCS_FETCH_ERROR
- // QRCS_REQUEST_TIMEOUT
- // QRCS_INSUFFICIENT_MEMORY
- // QRCS_LOST_NET
- // QRCS_NOT_SUPPORTED
- // QRCS_NOT_FOUND
- // Note: have converted it to ResultCode.
public int mCmdStatus;
//filled after IQPresListener_CMDStatus
@@ -77,10 +62,9 @@ public class Task{
// filled after IQPresListener_SipResponseReceived
public String mSipReasonPhrase;
- // filled before send the request
- public IRcsPresenceListener mListener;
+ public ContactCapabilityResponse mListener;
- public Task(int taskId, int cmdId, IRcsPresenceListener listener){
+ public Task(int taskId, int cmdId, ContactCapabilityResponse listener) {
mTaskId = taskId;
mCmdId = cmdId;
mListener = listener;
diff --git a/rcs/rcsservice/src/com/android/service/ims/TaskManager.java b/rcs/rcsservice/src/com/android/service/ims/TaskManager.java
index a643861..076a244 100644
--- a/rcs/rcsservice/src/com/android/service/ims/TaskManager.java
+++ b/rcs/rcsservice/src/com/android/service/ims/TaskManager.java
@@ -35,8 +35,8 @@ import android.os.Looper;
import android.os.Message;
import android.telephony.PhoneNumberUtils;
-import com.android.ims.IRcsPresenceListener;
import com.android.ims.internal.Logger;
+import com.android.service.ims.presence.ContactCapabilityResponse;
import com.android.service.ims.presence.PresenceAvailabilityTask;
import com.android.service.ims.presence.PresenceCapabilityTask;
import com.android.service.ims.presence.PresenceTask;
@@ -109,7 +109,7 @@ public class TaskManager{
}
public int addCapabilityTask(Context context, String[] contacts,
- IRcsPresenceListener listener, long timeout){
+ ContactCapabilityResponse listener, long timeout){
int taskId = TaskManager.getDefault().generateTaskId();
synchronized (mSyncObj){
Task task = new PresenceCapabilityTask(context, taskId, TASK_TYPE_GET_CAPABILITY,
@@ -120,7 +120,7 @@ public class TaskManager{
return taskId;
}
- public int addAvailabilityTask(String contact, IRcsPresenceListener listener){
+ public int addAvailabilityTask(String contact, ContactCapabilityResponse listener){
int taskId = TaskManager.getDefault().generateTaskId();
synchronized (mSyncObj){
String[] contacts = new String[1];
@@ -133,12 +133,12 @@ public class TaskManager{
return taskId;
}
- public int addPublishTask(String contact, IRcsPresenceListener listener){
+ public int addPublishTask(String contact){
int taskId = TaskManager.getDefault().generateTaskId();
synchronized (mSyncObj){
String[] contacts = new String[1];
contacts[0] = contact;
- Task task = new PresenceTask(taskId, TASK_TYPE_PUBLISH, listener, contacts);
+ Task task = new PresenceTask(taskId, TASK_TYPE_PUBLISH, null /*listener*/, contacts);
putTaskInternal(taskId, task);
}
@@ -162,6 +162,32 @@ public class TaskManager{
}
}
+ public Task getTaskForSingleContactQuery(String contact) {
+ synchronized (mSyncObj){
+ Set<String> keys= mTaskMap.keySet();
+ if(keys == null){
+ logger.debug("getTaskByContact keys=null");
+ return null;
+ }
+
+ for(String key:keys){
+ Task task = mTaskMap.get(key);
+ if(task == null){
+ continue;
+ }
+
+ if (task instanceof PresenceTask) {
+ PresenceTask presenceTask = (PresenceTask) task;
+ if(presenceTask.mContacts.length == 1 &&
+ PhoneNumberUtils.compare(contact, presenceTask.mContacts[0])){
+ return task;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
public Task getTaskByRequestId(int sipRequestId){
synchronized (mSyncObj){
Set<String> keys= mTaskMap.keySet();
diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/ContactCapabilityResponse.java b/rcs/rcsservice/src/com/android/service/ims/presence/ContactCapabilityResponse.java
new file mode 100644
index 0000000..5eb3154
--- /dev/null
+++ b/rcs/rcsservice/src/com/android/service/ims/presence/ContactCapabilityResponse.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2019, The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of The Android Open Source Project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+
+package com.android.service.ims.presence;
+
+import android.telephony.ims.RcsContactUceCapability;
+
+import java.util.List;
+
+public interface ContactCapabilityResponse {
+
+ /**
+ * Called when a capability request returns a "200 OK" (means capable) or "404 xxxx" for SIP
+ * request of single contact number (means not capable).
+ *
+ * @param reqId the request ID which is returned by requestCapability or
+ * requestAvailability
+ */
+ void onSuccess(int reqId);
+
+ /**
+ * Called when a local error is generated a SIP error is generated from the network.
+ *
+ * @param reqId the request ID which is returned by requestCapability or
+ * requestAvailability
+ * @param resultCode the result code which is defined in RcsManager.ResultCode.
+ */
+ void onError(int reqId, int resultCode);
+
+ /**
+ * Called when the request returns a "terminated notify" indication from the network.
+ * The presence service will not receive any more notifications for the request after this
+ * indication is received.
+ *
+ * @param reqId the request ID which is returned by requestCapability or
+ * requestAvailability
+ */
+ void onFinish(int reqId);
+
+ /**
+ * Called when there is a timeout waiting for the "terminated notify" indication from the
+ * network.
+ *
+ * @param reqId the request ID which is returned by requestCapability or
+ * requestAvailability.
+ */
+ void onTimeout(int reqId);
+
+ /**
+ * Called when there is an update to the capabilities from the network. On error, the
+ * capabilities will also be updates as not capable.
+ */
+ void onCapabilitiesUpdated(List<RcsContactUceCapability> contactCapabilities,
+ boolean updateLastTimestamp);
+}
diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceAvailabilityTask.java b/rcs/rcsservice/src/com/android/service/ims/presence/PresenceAvailabilityTask.java
index a008589..08a5b32 100644
--- a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceAvailabilityTask.java
+++ b/rcs/rcsservice/src/com/android/service/ims/presence/PresenceAvailabilityTask.java
@@ -28,7 +28,6 @@
package com.android.service.ims.presence;
-import com.android.ims.IRcsPresenceListener;
import com.android.ims.internal.Logger;
/**
@@ -45,7 +44,7 @@ public class PresenceAvailabilityTask extends PresenceTask{
// Time when get the notify. Used to check the 60s expires.
private long mNotifyTimeStamp = 0;
- public PresenceAvailabilityTask(int taskId, int cmdId, IRcsPresenceListener listener,
+ public PresenceAvailabilityTask(int taskId, int cmdId, ContactCapabilityResponse listener,
String[] contacts){
super(taskId, cmdId, listener, contacts);
diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceBase.java b/rcs/rcsservice/src/com/android/service/ims/presence/PresenceBase.java
index abe6fd7..9ffcba1 100644
--- a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceBase.java
+++ b/rcs/rcsservice/src/com/android/service/ims/presence/PresenceBase.java
@@ -28,61 +28,110 @@
package com.android.service.ims.presence;
+import android.annotation.IntDef;
import android.content.Context;
-import android.os.RemoteException;
import android.content.Intent;
-import com.android.ims.internal.uce.presence.PresCmdStatus;
-import com.android.ims.internal.uce.presence.PresSipResponse;
-import com.android.ims.RcsManager.ResultCode;
-import com.android.ims.RcsPresence.PublishState;
+import com.android.ims.ResultCode;
import com.android.ims.internal.Logger;
import com.android.internal.telephony.TelephonyIntents;
import com.android.service.ims.Task;
-import com.android.service.ims.RcsUtils;
import com.android.service.ims.TaskManager;
-public abstract class PresenceBase{
- /*
- * The logger
- */
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+public class PresenceBase {
static private Logger logger = Logger.getLogger("PresenceBase");
- protected Context mContext = null;
+ protected Context mContext;
+
+ /**
+ * The phone is PUBLISH_STATE_200_OK when
+ * the response of the last publish is "200 OK"
+ */
+ public static final int PUBLISH_STATE_200_OK = 0;
+
+ /**
+ * The phone didn't publish after power on.
+ * the phone didn't get any publish response yet.
+ */
+ public static final int PUBLISH_STATE_NOT_PUBLISHED = 1;
+
+ /**
+ * The phone is PUBLISH_STATE_VOLTE_PROVISION_ERROR when the response is one of items
+ * in config_volte_provision_error_on_publish_response for PUBLISH or
+ * in config_volte_provision_error_on_subscribe_response for SUBSCRIBE.
+ */
+ public static final int PUBLISH_STATE_VOLTE_PROVISION_ERROR = 2;
+
+ /**
+ * The phone is PUBLISH_STATE_RCS_PROVISION_ERROR when the response is one of items
+ * in config_rcs_provision_error_on_publish_response for PUBLISH or
+ * in config_rcs_provision_error_on_subscribe_response for SUBSCRIBE.Publ
+ */
+ public static final int PUBLISH_STATE_RCS_PROVISION_ERROR = 3;
- public PresenceBase() {
+ /**
+ * The phone is PUBLISH_STATE_REQUEST_TIMEOUT when
+ * The response of the last publish is "408 Request Timeout".
+ */
+ public static final int PUBLISH_STATE_REQUEST_TIMEOUT = 4;
+
+ /**
+ * The phone is PUBLISH_STATE_OTHER_ERROR when
+ * the response of the last publish is other temp error. Such as
+ * 503 Service Unavailable
+ * Device shall retry with exponential back-off
+ *
+ * 423 Interval Too Short. Requested expiry interval too short and server rejects it
+ * Device shall re-attempt subscription after changing the expiration interval in
+ * the Expires header field to be equal to or greater than the expiration interval
+ * within the Min-Expires header field of the 423 response.
+ */
+ public static final int PUBLISH_STATE_OTHER_ERROR = 5;
+
+ @IntDef(value = {
+ PUBLISH_STATE_200_OK,
+ PUBLISH_STATE_NOT_PUBLISHED,
+ PUBLISH_STATE_VOLTE_PROVISION_ERROR,
+ PUBLISH_STATE_RCS_PROVISION_ERROR,
+ PUBLISH_STATE_REQUEST_TIMEOUT,
+ PUBLISH_STATE_OTHER_ERROR
+ }, prefix="PUBLISH_STATE_")
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface PresencePublishState {}
+
+ public PresenceBase(Context context) {
+ mContext = context;
}
- protected void handleCallback(Task task, int resultCode, boolean forCmdStatus){
- if(task == null){
+ protected void handleCallback(Task task, int resultCode, boolean forCmdStatus) {
+ if (task == null) {
logger.debug("task == null");
return;
}
- if(task.mListener != null){
- try{
- if(resultCode >= ResultCode.SUCCESS){
- if(!forCmdStatus){
- task.mListener.onSuccess(task.mTaskId);
- }
- }else{
- task.mListener.onError(task.mTaskId, resultCode);
+ if (task.mListener != null) {
+ if(resultCode >= ResultCode.SUCCESS){
+ if(!forCmdStatus){
+ task.mListener.onSuccess(task.mTaskId);
}
- }catch(RemoteException e){
- logger.debug("Failed to send the status to client.");
+ }else{
+ task.mListener.onError(task.mTaskId, resultCode);
}
}
// remove task when error
// remove task when SIP response success.
// For list capability polling we will waiting for the terminated notify or timeout.
- if(resultCode != ResultCode.SUCCESS){
+ if (resultCode != ResultCode.SUCCESS) {
if(task instanceof PresencePublishTask){
PresencePublishTask publishTask = (PresencePublishTask) task;
logger.debug("handleCallback for publishTask=" + publishTask);
- if(resultCode == PublishState.PUBLISH_STATE_VOLTE_PROVISION_ERROR) {
+ if(resultCode == PUBLISH_STATE_VOLTE_PROVISION_ERROR) {
// retry 3 times for "403 Not Authorized for Presence".
- if(publishTask.getRetryCount() >= 3) {
+ if (publishTask.getRetryCount() >= 3) {
//remove capability after try 3 times by PresencePolling
logger.debug("handleCallback remove task=" + task);
TaskManager.getDefault().removeTask(task.mTaskId);
@@ -121,16 +170,10 @@ public abstract class PresenceBase{
}
}
- public void handleCmdStatus(PresCmdStatus pCmdStatus){
- if(pCmdStatus == null){
- logger.error("handleCallbackForCmdStatus pCmdStatus=null");
- return;
- }
-
- Task task = TaskManager.getDefault().getTask(pCmdStatus.getUserData());
- int resultCode = RcsUtils.statusCodeToResultCode(pCmdStatus.getStatus().getStatusCode());
- if(task != null){
- task.mSipRequestId = pCmdStatus.getRequestId();
+ public void onCommandStatusUpdated(int taskId, int requestId, int resultCode) {
+ Task task = TaskManager.getDefault().getTask(taskId);
+ if (task != null){
+ task.mSipRequestId = requestId;
task.mCmdStatus = resultCode;
TaskManager.getDefault().putTask(task.mTaskId, task);
}
@@ -167,7 +210,5 @@ public abstract class PresenceBase{
}
return false;
}
-
- abstract public void handleSipResponse(PresSipResponse pSipResponse);
}
diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceCapabilityTask.java b/rcs/rcsservice/src/com/android/service/ims/presence/PresenceCapabilityTask.java
index ff69915..e94e51a 100644
--- a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceCapabilityTask.java
+++ b/rcs/rcsservice/src/com/android/service/ims/presence/PresenceCapabilityTask.java
@@ -32,11 +32,9 @@ import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
-import android.os.RemoteException;
import android.os.SystemClock;
import com.android.ims.internal.Logger;
-import com.android.ims.IRcsPresenceListener;
import com.android.service.ims.TaskManager;
/**
@@ -48,6 +46,9 @@ public class PresenceCapabilityTask extends PresenceTask{
*/
private Logger logger = Logger.getLogger(this.getClass().getName());
+ /**
+ * PendingIntent Action that will be scheduled via AlarmManager as a task timeout.
+ */
public static final String ACTION_TASK_TIMEOUT_ALARM =
"com.android.service.ims.presence.task.timeout";
@@ -70,7 +71,7 @@ public class PresenceCapabilityTask extends PresenceTask{
private long mTimeout;
public PresenceCapabilityTask(Context context, int taskId, int cmdId,
- IRcsPresenceListener listener, String[] contacts,
+ ContactCapabilityResponse listener, String[] contacts,
long timeout){
super(taskId, cmdId, listener, contacts);
mContext = context;
@@ -105,7 +106,7 @@ public class PresenceCapabilityTask extends PresenceTask{
}
Intent intent = new Intent(ACTION_TASK_TIMEOUT_ALARM);
- intent.setClass(mContext, AlarmBroadcastReceiver.class);
+ intent.setPackage(mContext.getPackageName());
intent.putExtra("taskId", mTaskId);
PendingIntent mAlarmIntent = PendingIntent.getBroadcast(mContext, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
@@ -133,14 +134,9 @@ public class PresenceCapabilityTask extends PresenceTask{
public void onTimeout(){
logger.debug("onTimeout, taskId=" + mTaskId);
- try{
- if(mListener != null){
- mListener.onTimeout(mTaskId);
- }
- }catch (RemoteException e){
- logger.error("RemoteException", e);
+ if(mListener != null){
+ mListener.onTimeout(mTaskId);
}
-
TaskManager.getDefault().removeTask(mTaskId);
}
@@ -159,12 +155,8 @@ public class PresenceCapabilityTask extends PresenceTask{
}
cancelTimer();
- try{
- if(mListener != null){
- mListener.onFinish(mTaskId);
- }
- }catch (RemoteException e){
- logger.error("RemoteException", e);
+ if(mListener != null){
+ mListener.onFinish(mTaskId);
}
TaskManager.getDefault().removeTask(mTaskId);
diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/PresencePublication.java b/rcs/rcsservice/src/com/android/service/ims/presence/PresencePublication.java
index f827622..62c5091 100644
--- a/rcs/rcsservice/src/com/android/service/ims/presence/PresencePublication.java
+++ b/rcs/rcsservice/src/com/android/service/ims/presence/PresencePublication.java
@@ -28,46 +28,40 @@
package com.android.service.ims.presence;
-import java.util.Arrays;
-
+import android.annotation.IntDef;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
-import com.android.internal.telephony.Phone;
+import android.content.IntentFilter;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemClock;
import android.provider.Settings;
-import android.os.SystemProperties;
-import android.content.BroadcastReceiver;
+import android.telecom.PhoneAccount;
+import android.telecom.TelecomManager;
import android.telephony.AccessNetworkConstants;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
-
-import android.telecom.TelecomManager;
-import android.content.IntentFilter;
-import android.app.PendingIntent;
-import android.app.AlarmManager;
-import android.os.SystemClock;
-import android.os.Message;
-import android.os.Handler;
+import android.telephony.ims.RcsContactUceCapability;
import android.telephony.ims.feature.MmTelFeature;
-
-import com.android.ims.ImsManager;
-import com.android.ims.ImsServiceClass;
import com.android.ims.ImsConfig;
+import com.android.ims.ImsManager;
+import com.android.ims.ResultCode;
import com.android.ims.internal.Logger;
-import com.android.ims.internal.uce.presence.PresPublishTriggerType;
-import com.android.ims.internal.uce.presence.PresSipResponse;
-import com.android.ims.internal.uce.presence.PresCmdStatus;
-import com.android.ims.RcsPresenceInfo;
-import com.android.ims.IRcsPresenceListener;
-import com.android.ims.RcsManager.ResultCode;
-import com.android.ims.RcsPresence.PublishState;
import com.android.internal.telephony.IccCardConstants;
+import com.android.internal.telephony.Phone;
import com.android.internal.telephony.TelephonyIntents;
import com.android.service.ims.RcsSettingUtils;
-import com.android.service.ims.RcsStackAdaptor;
import com.android.service.ims.Task;
import com.android.service.ims.TaskManager;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
public class PresencePublication extends PresenceBase {
private Logger logger = Logger.getLogger(this.getClass().getName());
@@ -88,37 +82,11 @@ public class PresencePublication extends PresenceBase {
volatile PublishRequest mPublishedRequest = null;
/*
- * Message to notify for a publish
- */
- public static final int MESSAGE_RCS_PUBLISH_REQUEST = 1;
-
- /**
- * Publisher Error base
- */
- public static final int PUBLISH_ERROR_CODE_START = ResultCode.SUBSCRIBER_ERROR_CODE_END;
-
- /**
- * All publish errors not covered by specific errors
- */
- public static final int PUBLISH_GENIRIC_FAILURE = PUBLISH_ERROR_CODE_START - 1;
-
- /**
- * Responding for 403 - not authorized
+ * Message sent to mMsgHandler when there is a new request to Publish capabilities.
*/
- public static final int PUBLISH_NOT_AUTHORIZED_FOR_PRESENCE = PUBLISH_ERROR_CODE_START - 2;
+ private static final int MESSAGE_RCS_PUBLISH_REQUEST = 1;
- /**
- * Responding for 404 error code. The subscriber is not provisioned.
- * The Client should not send any EAB traffic after get this error.
- */
- public static final int PUBLISH_NOT_PROVISIONED = PUBLISH_ERROR_CODE_START - 3;
-
- /**
- * Responding for 200 - OK
- */
- public static final int PUBLISH_SUCESS = ResultCode.SUCCESS;
-
- private RcsStackAdaptor mRcsStackAdaptor = null;
+ private PresencePublisher mPresencePublisher;
private PresenceSubscriber mSubscriber = null;
static private PresencePublication sPresencePublication = null;
private BroadcastReceiver mReceiver = null;
@@ -135,7 +103,43 @@ public class PresencePublication extends PresenceBase {
private final String[] mConfigVolteProvisionErrorOnPublishResponse;
private final String[] mConfigRcsProvisionErrorOnPublishResponse;
- public class PublishType{
+ /** ETag expired. */
+ public static final int UCE_PRES_PUBLISH_TRIGGER_ETAG_EXPIRED = 0;
+ /** Move to LTE with VoPS disabled. */
+ public static final int UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED = 1;
+ /** Move to LTE with VoPS enabled. */
+ public static final int UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED = 2;
+ /** Move to eHRPD. */
+ public static final int UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_EHRPD = 3;
+ /** Move to HSPA+. */
+ public static final int UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_HSPAPLUS = 4;
+ /** Move to 3G. */
+ public static final int UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_3G = 5;
+ /** Move to 2G. */
+ public static final int UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_2G = 6;
+ /** Move to WLAN */
+ public static final int UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_WLAN = 7;
+ /** Move to IWLAN */
+ public static final int UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_IWLAN = 8;
+ /** Trigger is unknown. */
+ public static final int UCE_PRES_PUBLISH_TRIGGER_UNKNOWN = 9;
+
+ @IntDef(value = {
+ UCE_PRES_PUBLISH_TRIGGER_ETAG_EXPIRED,
+ UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED,
+ UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED,
+ UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_EHRPD,
+ UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_HSPAPLUS,
+ UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_3G,
+ UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_2G,
+ UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_WLAN,
+ UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_IWLAN,
+ UCE_PRES_PUBLISH_TRIGGER_UNKNOWN
+ }, prefix="UCE_PRES_PUBLISH_TRIGGER_")
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface StackPublishTriggerType {}
+
+ public class PublishType {
public static final int PRES_PUBLISH_TRIGGER_DATA_CHANGED = 0;
// the lower layer should send trigger when enable volte
// the lower layer should unpublish when disable volte
@@ -147,17 +151,12 @@ public class PresencePublication extends PresenceBase {
public static final int PRES_PUBLISH_TRIGGER_FEATURE_AVAILABILITY_CHANGED = 5;
};
- /**
- * @param rcsStackAdaptor
- * @param context
- */
- public PresencePublication(RcsStackAdaptor rcsStackAdaptor, Context context,
+ public PresencePublication(PresencePublisher presencePublisher, Context context,
String[] configVolteProvisionErrorOnPublishResponse,
String[] configRcsProvisionErrorOnPublishResponse) {
- super();
+ super(context);
logger.debug("PresencePublication constrcuct");
- this.mRcsStackAdaptor = rcsStackAdaptor;
- this.mContext = context;
+ this.mPresencePublisher = presencePublisher;
mConfigVolteProvisionErrorOnPublishResponse = configVolteProvisionErrorOnPublishResponse;
mConfigRcsProvisionErrorOnPublishResponse = configRcsProvisionErrorOnPublishResponse;
@@ -176,12 +175,6 @@ public class PresencePublication extends PresenceBase {
Phone.TTY_MODE_OFF);
logger.debug("The current TTY mode is: " + mPreferredTtyMode);
- if(mRcsStackAdaptor != null){
- mRcsStackAdaptor.setPublishState(
- SystemProperties.getInt("rcs.publish.status",
- PublishState.PUBLISH_STATE_NOT_PUBLISHED));
- }
-
mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -214,7 +207,7 @@ public class PresencePublication extends PresenceBase {
// treate hot SIM hot swap as power on.
mDonotRetryUntilPowerCycle = false;
if(mHasCachedTrigger) {
- invokePublish(PresencePublication.PublishType.
+ requestLocalPublish(PublishType.
PRES_PUBLISH_TRIGGER_CACHED_TRIGGER);
}
break;
@@ -235,16 +228,14 @@ public class PresencePublication extends PresenceBase {
// only reset when the SIM gets absent.
reset();
mSimLoaded = false;
- setPublishState(
- PublishState.PUBLISH_STATE_NOT_PUBLISHED);
+ setPublishState(PUBLISH_STATE_NOT_PUBLISHED);
}
}else if(Intent.ACTION_AIRPLANE_MODE_CHANGED.equalsIgnoreCase(intent.getAction())){
boolean airplaneMode = intent.getBooleanExtra("state", false);
if(airplaneMode){
logger.print("Airplane mode, set to PUBLISH_STATE_NOT_PUBLISHED");
reset();
- setPublishState(
- PublishState.PUBLISH_STATE_NOT_PUBLISHED);
+ setPublishState(PUBLISH_STATE_NOT_PUBLISHED);
}
}else if(TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED.equalsIgnoreCase(
intent.getAction())){
@@ -261,7 +252,7 @@ public class PresencePublication extends PresenceBase {
if (mIsTtyEnabled != isTtyEnabled) {
logger.print("ttyEnabled status changed from " + mIsTtyEnabled
+ " to " + isTtyEnabled);
- invokePublish(PresencePublication.PublishType.
+ requestLocalPublish(PublishType.
PRES_PUBLISH_TRIGGER_TTY_ENABLE_STATUS);
}
} else if(ImsConfig.ACTION_IMS_FEATURE_CHANGED.equalsIgnoreCase(
@@ -421,7 +412,7 @@ public class PresencePublication extends PresenceBase {
logger.debug("provisioned, set mDonotRetryUntilPowerCycle to false");
mDonotRetryUntilPowerCycle = false;
if(mHasCachedTrigger) {
- invokePublish(PresencePublication.PublishType.PRES_PUBLISH_TRIGGER_CACHED_TRIGGER);
+ requestLocalPublish(PublishType.PRES_PUBLISH_TRIGGER_CACHED_TRIGGER);
}
}
}
@@ -445,8 +436,7 @@ public class PresencePublication extends PresenceBase {
mDataEnabled = value;
RcsSettingUtils.setMobileDataEnabled(mContext, mDataEnabled);
- invokePublish(
- PresencePublication.PublishType.PRES_PUBLISH_TRIGGER_DATA_CHANGED);
+ requestLocalPublish(PublishType.PRES_PUBLISH_TRIGGER_DATA_CHANGED);
}
}
@@ -455,11 +445,16 @@ public class PresencePublication extends PresenceBase {
if(mVtEnabled != enabled) {
mVtEnabled = enabled;
- invokePublish(PresencePublication.PublishType.
- PRES_PUBLISH_TRIGGER_VTCALL_CHANGED);
+ requestLocalPublish(PublishType.PRES_PUBLISH_TRIGGER_VTCALL_CHANGED);
}
}
+ @Override
+ public void onCommandStatusUpdated(int taskId, int requestId, int resultCode) {
+ logger.info("onCommandStatusUpdated: resultCode= " + resultCode);
+ super.onCommandStatusUpdated(taskId, requestId, resultCode);
+ }
+
/**
* @return return true if it had been PUBLISHED.
*/
@@ -471,36 +466,30 @@ public class PresencePublication extends PresenceBase {
(System.currentTimeMillis() - mPublishingRequest.getTimestamp()
<= publishThreshold);
- return (getPublishState() == PublishState.PUBLISH_STATE_200_OK || publishing);
+ return (getPublishState() == PUBLISH_STATE_200_OK || publishing);
}
/**
- * @return the Publish State
+ * @return The result of the last Publish request.
*/
- public int getPublishState() {
- if(mRcsStackAdaptor == null){
- return PublishState.PUBLISH_STATE_NOT_PUBLISHED;
+ public @PresenceBase.PresencePublishState int getPublishState() {
+ if (mPresencePublisher != null) {
+ return mPresencePublisher.getPublisherState();
}
-
- return mRcsStackAdaptor.getPublishState();
+ return PUBLISH_STATE_NOT_PUBLISHED;
}
/**
- * @param mPublishState the publishState to set
+ * @param publishState The result of the last publish request.
*/
public void setPublishState(int publishState) {
- if(mRcsStackAdaptor != null){
- mRcsStackAdaptor.setPublishState(publishState);
+ if (mPresencePublisher != null) {
+ mPresencePublisher.updatePublisherState(publishState);
}
}
- public boolean getHasCachedTrigger(){
- return mHasCachedTrigger;
- }
-
- // Tiggered by framework.
- public int invokePublish(int trigger){
- int ret;
+ // Trigger a local publish based off of state changes in the framework.
+ private void requestLocalPublish(int trigger) {
// if the value is true then it will call stack to send the PUBLISH
// though the previous publish had the same capability
@@ -553,26 +542,26 @@ public class PresencePublication extends PresenceBase {
if(mGotTriggerFromStack == false){
// Waiting for RCS stack get ready.
logger.print("Didn't get trigger from stack yet, discard framework trigger.");
- return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
+ return;
}
if (mDonotRetryUntilPowerCycle) {
logger.print("Don't publish until next power cycle");
- return ResultCode.SUCCESS;
+ return;
}
if(!mSimLoaded){
//need to read some information from SIM to publish
logger.print("invokePublish cache the trigger since the SIM is not ready");
mHasCachedTrigger = true;
- return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
+ return;
}
//the provision status didn't be read from modem yet
if(!RcsSettingUtils.isEabProvisioned(mContext)) {
logger.print("invokePublish cache the trigger, not provision yet");
mHasCachedTrigger = true;
- return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
+ return;
}
PublishRequest publishRequest = new PublishRequest(
@@ -580,25 +569,20 @@ public class PresencePublication extends PresenceBase {
requestPublication(publishRequest);
- return ResultCode.SUCCESS;
+ return;
}
- public int invokePublish(PresPublishTriggerType val) {
- int ret;
-
+ public void onStackPublishRequested(@StackPublishTriggerType int publishTriggerType) {
mGotTriggerFromStack = true;
- // Always send the PUBLISH when we got the trigger from stack.
- // This can avoid any issue when switch the phone between IWLAN and LTE.
- boolean bForceToNetwork = true;
- switch (val.getPublishTrigeerType())
+ switch (publishTriggerType)
{
- case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_ETAG_EXPIRED:
+ case UCE_PRES_PUBLISH_TRIGGER_ETAG_EXPIRED:
{
logger.print("PUBLISH_TRIGGER_ETAG_EXPIRED");
break;
}
- case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED:
+ case UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED:
{
logger.print("PUBLISH_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED");
mMovedToLTE = true;
@@ -609,7 +593,7 @@ public class PresencePublication extends PresenceBase {
mImsRegistered = true;
break;
}
- case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED:
+ case UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED:
{
logger.print("PUBLISH_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED");
mMovedToLTE = true;
@@ -620,7 +604,7 @@ public class PresencePublication extends PresenceBase {
mImsRegistered = true;
break;
}
- case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_IWLAN:
+ case UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_IWLAN:
{
logger.print("QRCS_PRES_PUBLISH_TRIGGER_MOVE_TO_IWLAN");
mMovedToLTE = false;
@@ -631,7 +615,7 @@ public class PresencePublication extends PresenceBase {
mImsRegistered = true;
break;
}
- case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_EHRPD:
+ case UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_EHRPD:
{
logger.print("PUBLISH_TRIGGER_MOVE_TO_EHRPD");
mMovedToLTE = false;
@@ -642,7 +626,7 @@ public class PresencePublication extends PresenceBase {
mImsRegistered = true;
break;
}
- case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_HSPAPLUS:
+ case UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_HSPAPLUS:
{
logger.print("PUBLISH_TRIGGER_MOVE_TO_HSPAPLUS");
mMovedToLTE = false;
@@ -650,7 +634,7 @@ public class PresencePublication extends PresenceBase {
mMovedToIWLAN = false;
break;
}
- case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_2G:
+ case UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_2G:
{
logger.print("PUBLISH_TRIGGER_MOVE_TO_2G");
mMovedToLTE = false;
@@ -658,7 +642,7 @@ public class PresencePublication extends PresenceBase {
mMovedToIWLAN = false;
break;
}
- case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_3G:
+ case UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_3G:
{
logger.print("PUBLISH_TRIGGER_MOVE_TO_3G");
mMovedToLTE = false;
@@ -672,29 +656,38 @@ public class PresencePublication extends PresenceBase {
if (mDonotRetryUntilPowerCycle) {
logger.print("Don't publish until next power cycle");
- return ResultCode.SUCCESS;
+ return;
}
if(!mSimLoaded){
//need to read some information from SIM to publish
logger.print("invokePublish cache the trigger since the SIM is not ready");
mHasCachedTrigger = true;
- return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
+ return;
}
//the provision status didn't be read from modem yet
if(!RcsSettingUtils.isEabProvisioned(mContext)) {
logger.print("invokePublish cache the trigger, not provision yet");
mHasCachedTrigger = true;
- return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
+ return;
}
+ // Always send the PUBLISH when we got the trigger from stack.
+ // This can avoid any issue when switch the phone between IWLAN and LTE.
PublishRequest publishRequest = new PublishRequest(
- bForceToNetwork, System.currentTimeMillis());
+ true /*forceToNetwork*/, System.currentTimeMillis());
requestPublication(publishRequest);
+ }
- return ResultCode.SUCCESS;
+ /**
+ * Trigger a publish when the stack becomes available and we have a cached trigger waiting.
+ */
+ public void onStackAvailable() {
+ if (mHasCachedTrigger) {
+ requestLocalPublish(PublishType.PRES_PUBLISH_TRIGGER_CACHED_TRIGGER);
+ }
}
public class PublishRequest {
@@ -835,8 +828,8 @@ public class PresencePublication extends PresenceBase {
return;
}
- if (mRcsStackAdaptor == null) {
- logger.error("mRcsStackAdaptor == null");
+ if (mPresencePublisher == null) {
+ logger.error("mPresencePublisher == null");
return;
}
@@ -861,7 +854,7 @@ public class PresencePublication extends PresenceBase {
(publishRequest.hasSamePublishContent(mPublishingRequest) ||
(mPublishingRequest == null) &&
publishRequest.hasSamePublishContent(mPublishedRequest)) &&
- (getPublishState() != PublishState.PUBLISH_STATE_NOT_PUBLISHED)) {
+ (getPublishState() != PUBLISH_STATE_NOT_PUBLISHED)) {
logger.print("Don't need publish since the capability didn't change publishRequest " +
publishRequest + " getPublishState()=" + getPublishState());
return;
@@ -897,7 +890,7 @@ public class PresencePublication extends PresenceBase {
// we need send PUBLISH once even the volte is off when power on the phone.
// That will tell other phone that it has no volte/vt capability.
if(!getImsManager().isEnhanced4gLteModeSettingEnabledByUser() &&
- getPublishState() != PublishState.PUBLISH_STATE_NOT_PUBLISHED) {
+ getPublishState() != PUBLISH_STATE_NOT_PUBLISHED) {
// volte was not enabled.
// or it is turnning off volte. lower layer should unpublish
reset();
@@ -906,37 +899,35 @@ public class PresencePublication extends PresenceBase {
TelephonyManager teleMgr = (TelephonyManager) mContext.getSystemService(
Context.TELEPHONY_SERVICE);
- if(teleMgr ==null) {
- logger.debug("teleMgr=null");
+ if (teleMgr == null) {
+ logger.error("TelephonyManager not available.");
return;
- }
+ }
+ Uri contactUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, teleMgr.getLine1Number(), null);
- RcsPresenceInfo presenceInfo = new RcsPresenceInfo(teleMgr.getLine1Number(),
- RcsPresenceInfo.VolteStatus.VOLTE_UNKNOWN,
- publishRequest.getVolteCapable()?RcsPresenceInfo.ServiceState.ONLINE:
- RcsPresenceInfo.ServiceState.OFFLINE, null, System.currentTimeMillis(),
- publishRequest.getVtCapable()?RcsPresenceInfo.ServiceState.ONLINE:
- RcsPresenceInfo.ServiceState.OFFLINE, null,
- System.currentTimeMillis());
+ RcsContactUceCapability.Builder presenceInfoBuilder =
+ new RcsContactUceCapability.Builder(contactUri);
+ if (publishRequest.getVolteCapable()) {
+ presenceInfoBuilder.add(RcsContactUceCapability.CAPABILITY_IP_VOICE_CALL);
+ }
+ if (publishRequest.getVtCapable()) {
+ presenceInfoBuilder.add(RcsContactUceCapability.CAPABILITY_IP_VIDEO_CALL);
+ }
synchronized(mSyncObj) {
mPublishingRequest = publishRequest;
mPublishingRequest.setTimestamp(System.currentTimeMillis());
}
- int ret = mRcsStackAdaptor.requestPublication(presenceInfo, null);
- if(ret == ResultCode.ERROR_SERVICE_NOT_AVAILABLE){
+ int ret = mPresencePublisher.requestPublication(presenceInfoBuilder.build());
+ if (ret == ResultCode.ERROR_SERVICE_NOT_AVAILABLE) {
mHasCachedTrigger = true;
- }else{
+ } else {
//reset the cached trigger
mHasCachedTrigger = false;
}
}
- public void handleCmdStatus(PresCmdStatus cmdStatus) {
- super.handleCmdStatus(cmdStatus);
- }
-
private PendingIntent mRetryAlarmIntent = null;
public static final String ACTION_RETRY_PUBLISH_ALARM =
"com.android.service.ims.presence.retry.publish";
@@ -959,7 +950,7 @@ public class PresencePublication extends PresenceBase {
mCancelRetry = false;
Intent intent = new Intent(ACTION_RETRY_PUBLISH_ALARM);
- intent.setClass(mContext, AlarmBroadcastReceiver.class);
+ intent.setPackage(mContext.getPackageName());
mRetryAlarmIntent = PendingIntent.getBroadcast(mContext, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
@@ -981,28 +972,23 @@ public class PresencePublication extends PresenceBase {
return;
}
- invokePublish(PublishType.PRES_PUBLISH_TRIGGER_RETRY);
+ requestLocalPublish(PublishType.PRES_PUBLISH_TRIGGER_RETRY);
}
- public void handleSipResponse(PresSipResponse pSipResponse) {
- logger.print( "Publish response code = " + pSipResponse.getSipResponseCode()
- +"Publish response reason phrase = " + pSipResponse.getReasonPhrase());
+ public void onSipResponse(int requestId, int responseCode, String reasonPhrase) {
+ logger.print( "Publish response code = " + responseCode
+ +"Publish response reason phrase = " + reasonPhrase);
synchronized(mSyncObj) {
mPublishedRequest = mPublishingRequest;
mPublishingRequest = null;
}
- if(pSipResponse == null){
- logger.debug("handlePublishResponse pSipResponse = null");
- return;
- }
- int sipCode = pSipResponse.getSipResponseCode();
- if(isInConfigList(sipCode, pSipResponse.getReasonPhrase(),
+ if (isInConfigList(responseCode, reasonPhrase,
mConfigVolteProvisionErrorOnPublishResponse)) {
- logger.print("volte provision error. sipCode=" + sipCode + " phrase=" +
- pSipResponse.getReasonPhrase());
- setPublishState(PublishState.PUBLISH_STATE_VOLTE_PROVISION_ERROR);
+ logger.print("volte provision error. sipCode=" + responseCode + " phrase=" +
+ reasonPhrase);
+ setPublishState(PUBLISH_STATE_VOLTE_PROVISION_ERROR);
mDonotRetryUntilPowerCycle = true;
notifyDm();
@@ -1010,49 +996,47 @@ public class PresencePublication extends PresenceBase {
return;
}
- if(isInConfigList(sipCode, pSipResponse.getReasonPhrase(),
- mConfigRcsProvisionErrorOnPublishResponse)) {
- logger.print("rcs provision error.sipCode=" + sipCode + " phrase=" +
- pSipResponse.getReasonPhrase());
- setPublishState(PublishState.PUBLISH_STATE_RCS_PROVISION_ERROR);
+ if (isInConfigList(responseCode, reasonPhrase, mConfigRcsProvisionErrorOnPublishResponse)) {
+ logger.print("rcs provision error.sipCode=" + responseCode + " phrase=" + reasonPhrase);
+ setPublishState(PUBLISH_STATE_RCS_PROVISION_ERROR);
mDonotRetryUntilPowerCycle = true;
return;
}
- switch (sipCode) {
+ switch (responseCode) {
case 999:
logger.debug("Publish ignored - No capability change");
break;
case 200:
- setPublishState(PublishState.PUBLISH_STATE_200_OK);
+ setPublishState(PUBLISH_STATE_200_OK);
if(mSubscriber != null) {
mSubscriber.retryToGetAvailability();
}
break;
case 408:
- setPublishState(PublishState.PUBLISH_STATE_REQUEST_TIMEOUT);
+ setPublishState(PUBLISH_STATE_REQUEST_TIMEOUT);
break;
default: // Generic Failure
- if ((sipCode < 100) || (sipCode > 699)) {
- logger.debug("Ignore internal response code, sipCode=" + sipCode);
+ if ((responseCode < 100) || (responseCode > 699)) {
+ logger.debug("Ignore internal response code, sipCode=" + responseCode);
// internal error
// 0- PERMANENT ERROR: UI should not retry immediately
// 888- TEMP ERROR: UI Can retry immediately
// 999- NO CHANGE: No Publish needs to be sent
- if(sipCode == 888) {
+ if(responseCode == 888) {
// retry per 2 minutes
scheduleRetryPublish(120000);
} else {
- logger.debug("Ignore internal response code, sipCode=" + sipCode);
+ logger.debug("Ignore internal response code, sipCode=" + responseCode);
}
} else {
logger.debug( "Generic Failure");
- setPublishState(PublishState.PUBLISH_STATE_OTHER_ERROR);
+ setPublishState(PUBLISH_STATE_OTHER_ERROR);
- if ((sipCode>=400) && (sipCode <= 699)) {
+ if ((responseCode>=400) && (responseCode <= 699)) {
// 4xx/5xx/6xx, No retry, no impact on subsequent publish
logger.debug( "No Retry in OEM");
}
@@ -1061,11 +1045,10 @@ public class PresencePublication extends PresenceBase {
}
// Suppose the request ID had been set when IQPresListener_CMDStatus
- Task task = TaskManager.getDefault().getTaskByRequestId(
- pSipResponse.getRequestId());
+ Task task = TaskManager.getDefault().getTaskByRequestId(requestId);
if(task != null){
- task.mSipResponseCode = pSipResponse.getSipResponseCode();
- task.mSipReasonPhrase = pSipResponse.getReasonPhrase();
+ task.mSipResponseCode = responseCode;
+ task.mSipReasonPhrase = reasonPhrase;
}
handleCallback(task, getPublishState(), false);
@@ -1154,7 +1137,7 @@ public class PresencePublication extends PresenceBase {
if(isOnIWLAN()) {
// will check duplicated PUBLISH in requestPublication by invokePublish
- invokePublish(PresencePublication.PublishType.
+ requestLocalPublish(PublishType.
PRES_PUBLISH_TRIGGER_FEATURE_AVAILABILITY_CHANGED);
}
} else {
diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/PresencePublishTask.java b/rcs/rcsservice/src/com/android/service/ims/presence/PresencePublishTask.java
index 73ae4ca..24d1ada 100644
--- a/rcs/rcsservice/src/com/android/service/ims/presence/PresencePublishTask.java
+++ b/rcs/rcsservice/src/com/android/service/ims/presence/PresencePublishTask.java
@@ -28,23 +28,16 @@
package com.android.service.ims.presence;
-import com.android.ims.internal.Logger;
-import com.android.ims.IRcsPresenceListener;
-
/**
* PresencePublishTask
*/
public class PresencePublishTask extends PresenceTask{
- /*
- * The logger
- */
- private Logger logger = Logger.getLogger(this.getClass().getName());
private long mCreateTimestamp = 0;
private int mRetryCount = 0;
- public PresencePublishTask(int taskId, int cmdId, IRcsPresenceListener listener,
+ public PresencePublishTask(int taskId, int cmdId, ContactCapabilityResponse listener,
String[] contacts){
super(taskId, cmdId, listener, contacts);
diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/PresencePublisher.java b/rcs/rcsservice/src/com/android/service/ims/presence/PresencePublisher.java
new file mode 100644
index 0000000..4b6eb89
--- /dev/null
+++ b/rcs/rcsservice/src/com/android/service/ims/presence/PresencePublisher.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2019, The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of The Android Open Source Project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+
+package com.android.service.ims.presence;
+
+import android.telephony.ims.RcsContactUceCapability;
+
+public interface PresencePublisher {
+
+ /**
+ * Notify the stack of the last publish request result.
+ */
+ @PresenceBase.PresencePublishState int getPublisherState();
+
+ /**
+ * Request that the specified capabilities are published to the network.
+ * @param capabilities The capabilities to publish.
+ * @return the result of requesting that the capabilities are published.
+ */
+ int requestPublication(RcsContactUceCapability capabilities);
+
+ /**
+ * Notify the stack of the last publish or subscribe request result.
+ */
+ void updatePublisherState(@PresenceBase.PresencePublishState int publishState);
+}
diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceSubscriber.java b/rcs/rcsservice/src/com/android/service/ims/presence/PresenceSubscriber.java
index ccd4cae..9a7e6f9 100644
--- a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceSubscriber.java
+++ b/rcs/rcsservice/src/com/android/service/ims/presence/PresenceSubscriber.java
@@ -28,43 +28,24 @@
package com.android.service.ims.presence;
-import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
import android.telephony.TelephonyManager;
+import android.telephony.ims.RcsContactUceCapability;
import android.text.TextUtils;
-import com.android.ims.IRcsPresenceListener;
-import com.android.ims.RcsManager.ResultCode;
-import com.android.ims.RcsPresence;
-import com.android.ims.RcsPresence.PublishState;
-import com.android.ims.RcsPresenceInfo;
+import com.android.ims.ResultCode;
import com.android.ims.internal.ContactNumberUtils;
import com.android.ims.internal.Logger;
-import com.android.ims.internal.uce.presence.PresCmdStatus;
-import com.android.ims.internal.uce.presence.PresResInfo;
-import com.android.ims.internal.uce.presence.PresRlmiInfo;
-import com.android.ims.internal.uce.presence.PresSipResponse;
-import com.android.ims.internal.uce.presence.PresSubscriptionState;
-import com.android.ims.internal.uce.presence.PresTupleInfo;
import com.android.service.ims.RcsSettingUtils;
-import com.android.service.ims.RcsStackAdaptor;
-import com.android.service.ims.RcsUtils;
import com.android.service.ims.Task;
import com.android.service.ims.TaskManager;
-
import java.util.ArrayList;
import java.util.List;
-public class PresenceSubscriber extends PresenceBase{
- /*
- * The logger
- */
+public class PresenceSubscriber extends PresenceBase {
private Logger logger = Logger.getLogger(this.getClass().getName());
- private RcsStackAdaptor mRcsStackAdaptor = null;
-
- private static PresenceSubscriber sSubsriber = null;
+ private SubscribePublisher mSubscriber;
private String mAvailabilityRetryNumber = null;
@@ -74,11 +55,11 @@ public class PresenceSubscriber extends PresenceBase{
/*
* Constructor
*/
- public PresenceSubscriber(RcsStackAdaptor rcsStackAdaptor, Context context,
+ public PresenceSubscriber(SubscribePublisher subscriber, Context context,
String[] configVolteProvisionErrorOnSubscribeResponse,
String[] configRcsProvisionErrorOnSubscribeResponse){
- mRcsStackAdaptor = rcsStackAdaptor;
- mContext = context;
+ super(context);
+ mSubscriber = subscriber;
mConfigVolteProvisionErrorOnSubscribeResponse
= configVolteProvisionErrorOnSubscribeResponse;
mConfigRcsProvisionErrorOnSubscribeResponse = configRcsProvisionErrorOnSubscribeResponse;
@@ -111,10 +92,10 @@ public class PresenceSubscriber extends PresenceBase{
}
public int requestCapability(List<String> contactsNumber,
- IRcsPresenceListener listener){
+ ContactCapabilityResponse listener) {
- int ret = mRcsStackAdaptor.checkStackAndPublish();
- if(ret < ResultCode.SUCCESS){
+ int ret = mSubscriber.getStackStatusForCapabilityRequest();
+ if (ret < ResultCode.SUCCESS) {
logger.error("requestCapability ret=" + ret);
return ret;
}
@@ -132,10 +113,10 @@ public class PresenceSubscriber extends PresenceBase{
}
String[] formatedNumbers = ContactNumberUtils.getDefault().format(contactsNumber);
- ret = ContactNumberUtils.getDefault().validate(formatedNumbers);
- if(ret != ContactNumberUtils.NUMBER_VALID){
- logger.error("requestCapability ret=" + ret);
- return ret;
+ int formatResult = ContactNumberUtils.getDefault().validate(formatedNumbers);
+ if (formatResult != ContactNumberUtils.NUMBER_VALID) {
+ logger.error("requestCapability formatResult=" + formatResult);
+ return ResultCode.SUBSCRIBE_INVALID_PARAM;
}
String[] formatedContacts = new String[formatedNumbers.length];
@@ -153,13 +134,13 @@ public class PresenceSubscriber extends PresenceBase{
timeout += 3000;
logger.print("add to task manager, formatedNumbers=" +
- RcsUtils.toContactString(formatedNumbers));
+ PresenceUtils.toContactString(formatedNumbers));
int taskId = TaskManager.getDefault().addCapabilityTask(mContext, formatedNumbers,
listener, timeout);
logger.print("taskId=" + taskId);
- ret = mRcsStackAdaptor.requestCapability(formatedContacts, taskId);
- if(ret < ResultCode.SUCCESS){
+ ret = mSubscriber.requestCapability(formatedContacts, taskId);
+ if(ret < ResultCode.SUCCESS) {
logger.error("requestCapability ret=" + ret + " remove taskId=" + taskId);
TaskManager.getDefault().removeTask(taskId);
}
@@ -169,8 +150,8 @@ public class PresenceSubscriber extends PresenceBase{
return ret;
}
- public int requestAvailability(String contactNumber, IRcsPresenceListener listener,
- boolean forceToNetwork){
+ public int requestAvailability(String contactNumber, ContactCapabilityResponse listener,
+ boolean forceToNetwork) {
String formatedContact = ContactNumberUtils.getDefault().format(contactNumber);
int ret = ContactNumberUtils.getDefault().validate(formatedContact);
@@ -212,8 +193,8 @@ public class PresenceSubscriber extends PresenceBase{
return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
}
- ret = mRcsStackAdaptor.checkStackAndPublish();
- if(ret < ResultCode.SUCCESS){
+ ret = mSubscriber.getStackStatusForCapabilityRequest();
+ if (ret < ResultCode.SUCCESS) {
logger.error("requestAvailability=" + ret);
return ret;
}
@@ -226,19 +207,18 @@ public class PresenceSubscriber extends PresenceBase{
logger.print("addAvailabilityTask formatedContact=" + formatedContact);
- ret = mRcsStackAdaptor.requestAvailability(formatedContact, taskId);
- if(ret < ResultCode.SUCCESS){
+ ret = mSubscriber.requestAvailability(formatedContact, taskId);
+ if (ret < ResultCode.SUCCESS) {
logger.error("requestAvailability ret=" + ret + " remove taskId=" + taskId);
TaskManager.getDefault().removeTask(taskId);
}
ret = taskId;
- return ret;
+ return ret;
}
- private int translateResponse403(PresSipResponse pSipResponse){
- String reasonPhrase = pSipResponse.getReasonPhrase();
+ private int translateResponse403(String reasonPhrase){
if(reasonPhrase == null){
// No retry. The PS provisioning has not occurred correctly. UX Decision to show errror.
return ResultCode.SUBSCRIBE_GENIRIC_FAILURE;
@@ -260,26 +240,24 @@ public class PresenceSubscriber extends PresenceBase{
return ResultCode.SUBSCRIBE_FORBIDDEN;
}
- private int translateResponseCode(PresSipResponse pSipResponse){
+ private int translateResponseCode(int responseCode, String reasonPhrase) {
// pSipResponse should not be null.
- logger.debug("translateResponseCode getSipResponseCode=" +
- pSipResponse.getSipResponseCode());
+ logger.debug("translateResponseCode getSipResponseCode=" +responseCode);
int ret = ResultCode.SUBSCRIBE_GENIRIC_FAILURE;
- int sipCode = pSipResponse.getSipResponseCode();
- if(sipCode < 100 || sipCode > 699){
- logger.debug("internal error code sipCode=" + sipCode);
+ if(responseCode < 100 || responseCode > 699){
+ logger.debug("internal error code sipCode=" + responseCode);
ret = ResultCode.SUBSCRIBE_TEMPORARY_ERROR; //it is internal issue. ignore it.
return ret;
}
- switch(sipCode){
+ switch(responseCode){
case 200:
ret = ResultCode.SUCCESS;
break;
case 403:
- ret = translateResponse403(pSipResponse);
+ ret = translateResponse403(reasonPhrase);
break;
case 404:
@@ -340,32 +318,26 @@ public class PresenceSubscriber extends PresenceBase{
return ret;
}
- public void handleSipResponse(PresSipResponse pSipResponse){
- if(pSipResponse == null){
- logger.debug("handleSipResponse pSipResponse = null");
- return;
- }
-
- int sipCode = pSipResponse.getSipResponseCode();
- String phrase = pSipResponse.getReasonPhrase();
- if(isInConfigList(sipCode, phrase, mConfigVolteProvisionErrorOnSubscribeResponse)) {
- logger.print("volte provision sipCode=" + sipCode + " phrase=" + phrase);
- mRcsStackAdaptor.setPublishState(PublishState.PUBLISH_STATE_VOLTE_PROVISION_ERROR);
+ public void onSipResponse(int requestId, int responseCode, String reasonPhrase) {
+ if(isInConfigList(responseCode, reasonPhrase,
+ mConfigVolteProvisionErrorOnSubscribeResponse)) {
+ logger.print("volte provision sipCode=" + responseCode + " phrase=" + reasonPhrase);
+ mSubscriber.updatePublisherState(PUBLISH_STATE_VOLTE_PROVISION_ERROR);
notifyDm();
- } else if(isInConfigList(sipCode, phrase, mConfigRcsProvisionErrorOnSubscribeResponse)) {
- logger.print("rcs provision sipCode=" + sipCode + " phrase=" + phrase);
- mRcsStackAdaptor.setPublishState(PublishState.PUBLISH_STATE_RCS_PROVISION_ERROR);
+ } else if(isInConfigList(responseCode, reasonPhrase,
+ mConfigRcsProvisionErrorOnSubscribeResponse)) {
+ logger.print("rcs proRcsPresence.vision sipCode=" + responseCode + " phrase=" + reasonPhrase);
+ mSubscriber.updatePublisherState(PUBLISH_STATE_RCS_PROVISION_ERROR);
}
- int errorCode = translateResponseCode(pSipResponse);
+ int errorCode = translateResponseCode(responseCode, reasonPhrase);
logger.print("handleSipResponse errorCode=" + errorCode);
if(errorCode == ResultCode.SUBSCRIBE_NOT_REGISTERED){
logger.debug("setPublishState to unknown" +
" for subscribe error 403 not registered");
- mRcsStackAdaptor.setPublishState(
- PublishState.PUBLISH_STATE_OTHER_ERROR);
+ mSubscriber.updatePublisherState(PUBLISH_STATE_OTHER_ERROR);
}
if(errorCode == ResultCode.SUBSCRIBE_NOT_AUTHORIZED_FOR_PRESENCE) {
@@ -377,12 +349,11 @@ public class PresenceSubscriber extends PresenceBase{
}
// Suppose the request ID had been set when IQPresListener_CMDStatus
- Task task = TaskManager.getDefault().getTaskByRequestId(
- pSipResponse.getRequestId());
+ Task task = TaskManager.getDefault().getTaskByRequestId(requestId);
logger.debug("handleSipResponse task=" + task);
if(task != null){
- task.mSipResponseCode = sipCode;
- task.mSipReasonPhrase = phrase;
+ task.mSipResponseCode = responseCode;
+ task.mSipReasonPhrase = reasonPhrase;
TaskManager.getDefault().putTask(task.mTaskId, task);
}
@@ -400,27 +371,19 @@ public class PresenceSubscriber extends PresenceBase{
if(errorCode == ResultCode.SUBSCRIBE_NOT_FOUND &&
task != null && ((PresenceTask)task).mContacts != null) {
String[] contacts = ((PresenceTask)task).mContacts;
- ArrayList<RcsPresenceInfo> presenceInfoList = new ArrayList<RcsPresenceInfo>();
+ ArrayList<RcsContactUceCapability> contactCapabilities = new ArrayList<>();
for(int i=0; i<contacts.length; i++){
if(TextUtils.isEmpty(contacts[i])){
continue;
}
-
- RcsPresenceInfo presenceInfo = new RcsPresenceInfo(contacts[i],
- RcsPresenceInfo.VolteStatus.VOLTE_DISABLED,
- RcsPresenceInfo.ServiceState.OFFLINE, null, System.currentTimeMillis(),
- RcsPresenceInfo.ServiceState.OFFLINE, null, System.currentTimeMillis());
- presenceInfoList.add(presenceInfo);
+ logger.debug("onSipResponse: contact= " + contacts[i] + ", not found.");
+ // Build contacts with no capabilities.
+ contactCapabilities.add(new RcsContactUceCapability.Builder(
+ PresenceUtils.convertContactNumber(contacts[i])).build());
}
+ handleCapabilityUpdate(task, contactCapabilities, true);
- // Notify presence information changed.
- logger.debug("notify presence changed for 404 error");
- Intent intent = new Intent(RcsPresence.ACTION_PRESENCE_CHANGED);
- intent.putParcelableArrayListExtra(RcsPresence.EXTRA_PRESENCE_INFO_LIST,
- presenceInfoList);
- intent.putExtra("updateLastTimestamp", true);
- launchPersistService(intent);
} else if(errorCode == ResultCode.SUBSCRIBE_GENIRIC_FAILURE) {
updateAvailabilityToUnknown(task);
}
@@ -428,11 +391,13 @@ public class PresenceSubscriber extends PresenceBase{
handleCallback(task, errorCode, false);
}
- private void launchPersistService(Intent intent) {
- ComponentName component = new ComponentName("com.android.service.ims.presence",
- "com.android.service.ims.presence.PersistService");
- intent.setComponent(component);
- mContext.startService(intent);
+ private void handleCapabilityUpdate(Task task, List<RcsContactUceCapability> capabilities,
+ boolean updateLastTimestamp) {
+ if (task == null || task.mListener == null ) {
+ logger.warn("handleCapabilityUpdate, invalid listener!");
+ return;
+ }
+ task.mListener.onCapabilitiesUpdated(capabilities, updateLastTimestamp);
}
public void retryToGetAvailability() {
@@ -444,104 +409,52 @@ public class PresenceSubscriber extends PresenceBase{
mAvailabilityRetryNumber = null;
}
- public void updatePresence(String pPresentityUri, PresTupleInfo[] pTupleInfo){
+ public void updatePresence(RcsContactUceCapability capabilities) {
if(mContext == null){
logger.error("updatePresence mContext == null");
return;
}
- RcsPresenceInfo rcsPresenceInfo = PresenceInfoParser.getPresenceInfoFromTuple(
- pPresentityUri, pTupleInfo);
- if(rcsPresenceInfo == null || TextUtils.isEmpty(
- rcsPresenceInfo.getContactNumber())){
- logger.error("rcsPresenceInfo is null or " +
- "TextUtils.isEmpty(rcsPresenceInfo.getContactNumber()");
- return;
- }
-
- ArrayList<RcsPresenceInfo> rcsPresenceInfoList = new ArrayList<RcsPresenceInfo>();
- rcsPresenceInfoList.add(rcsPresenceInfo);
+ ArrayList<RcsContactUceCapability> presenceInfos = new ArrayList<>();
+ presenceInfos.add(capabilities);
+ String contactNumber = capabilities.getContactUri().getSchemeSpecificPart();
// For single contact number we got 1 NOTIFY only. So regard it as terminated.
- TaskManager.getDefault().onTerminated(rcsPresenceInfo.getContactNumber());
+ TaskManager.getDefault().onTerminated(contactNumber);
PresenceAvailabilityTask availabilityTask = TaskManager.getDefault().
- getAvailabilityTaskByContact(rcsPresenceInfo.getContactNumber());
- if(availabilityTask != null){
+ getAvailabilityTaskByContact(contactNumber);
+ if (availabilityTask != null) {
availabilityTask.updateNotifyTimestamp();
}
-
- // Notify presence information changed.
- Intent intent = new Intent(RcsPresence.ACTION_PRESENCE_CHANGED);
- intent.putParcelableArrayListExtra(RcsPresence.EXTRA_PRESENCE_INFO_LIST,
- rcsPresenceInfoList);
- intent.putExtra("updateLastTimestamp", true);
- launchPersistService(intent);
+ Task task = TaskManager.getDefault().getTaskForSingleContactQuery(contactNumber);
+ handleCapabilityUpdate(task, presenceInfos, true);
}
- public void updatePresences(PresRlmiInfo pRlmiInfo, PresResInfo[] pRcsPresenceInfo) {
+ public void updatePresences(int requestId, List<RcsContactUceCapability> contactsCapabilities,
+ boolean isTerminated, String terminatedReason) {
if(mContext == null){
logger.error("updatePresences: mContext == null");
return;
}
- RcsPresenceInfo[] rcsPresenceInfos = PresenceInfoParser.
- getPresenceInfosFromPresenceRes(pRlmiInfo, pRcsPresenceInfo);
- if(rcsPresenceInfos == null){
- logger.error("updatePresences: rcsPresenceInfos == null");
- return;
+ if (isTerminated) {
+ TaskManager.getDefault().onTerminated(requestId, terminatedReason);
}
- ArrayList<RcsPresenceInfo> rcsPresenceInfoList = new ArrayList<RcsPresenceInfo>();
-
- for (int i=0; i < rcsPresenceInfos.length; i++) {
- RcsPresenceInfo rcsPresenceInfo = rcsPresenceInfos[i];
- if(rcsPresenceInfo != null && !TextUtils.isEmpty(rcsPresenceInfo.getContactNumber())){
- logger.debug("rcsPresenceInfo=" + rcsPresenceInfo);
-
- rcsPresenceInfoList.add(rcsPresenceInfo);
- }
- }
-
- boolean isTerminated = false;
- if(pRlmiInfo.getPresSubscriptionState() != null){
- if(pRlmiInfo.getPresSubscriptionState().getPresSubscriptionStateValue() ==
- PresSubscriptionState.UCE_PRES_SUBSCRIPTION_STATE_TERMINATED){
- isTerminated = true;
- }
- }
-
- if(isTerminated){
- TaskManager.getDefault().onTerminated(pRlmiInfo.getRequestId(),
- pRlmiInfo.getSubscriptionTerminatedReason());
- }
-
- if (rcsPresenceInfoList.size() > 0) {
- // Notify presence changed
- Intent intent = new Intent(RcsPresence.ACTION_PRESENCE_CHANGED);
- intent.putParcelableArrayListExtra(RcsPresence.EXTRA_PRESENCE_INFO_LIST,
- rcsPresenceInfoList);
- logger.debug("broadcast ACTION_PRESENCE_CHANGED, rcsPresenceInfo=" +
- rcsPresenceInfoList);
- intent.putExtra("updateLastTimestamp", true);
- launchPersistService(intent);
+ Task task = TaskManager.getDefault().getTaskByRequestId(requestId);
+ if (contactsCapabilities.size() > 0 || task != null) {
+ handleCapabilityUpdate(task, contactsCapabilities, true);
}
}
- public void handleCmdStatus(PresCmdStatus pCmdStatus){
- if(pCmdStatus == null){
- logger.error("handleCallbackForCmdStatus pCmdStatus=null");
- return;
- }
-
-
- Task taskTmp = TaskManager.getDefault().getTask(pCmdStatus.getUserData());
- int resultCode = RcsUtils.statusCodeToResultCode(pCmdStatus.getStatus().getStatusCode());
+ public void onCommandStatusUpdated(int taskId, int requestId, int resultCode) {
+ Task taskTmp = TaskManager.getDefault().getTask(taskId);
logger.print("handleCmdStatus resultCode=" + resultCode);
PresenceTask task = null;
if(taskTmp != null && (taskTmp instanceof PresenceTask)){
task = (PresenceTask)taskTmp;
- task.mSipRequestId = pCmdStatus.getRequestId();
+ task.mSipRequestId = requestId;
task.mCmdStatus = resultCode;
TaskManager.getDefault().putTask(task.mTaskId, task);
@@ -579,30 +492,18 @@ public class PresenceSubscriber extends PresenceBase{
return;
}
- ArrayList<RcsPresenceInfo> presenceInfoList = new ArrayList<RcsPresenceInfo>();
- for(int i = 0; i< task.mContacts.length; i++){
- if(task.mContacts[i] == null || task.mContacts[i].length() == 0){
+ ArrayList<RcsContactUceCapability> presenceInfoList = new ArrayList<>();
+ for (int i = 0; i< task.mContacts.length; i++) {
+ if(TextUtils.isEmpty(task.mContacts[i])){
continue;
}
-
- RcsPresenceInfo presenceInfo = new RcsPresenceInfo(
- PresenceInfoParser.getPhoneFromUri(task.mContacts[i]),
- RcsPresenceInfo.VolteStatus.VOLTE_UNKNOWN,
- RcsPresenceInfo.ServiceState.UNKNOWN, null, System.currentTimeMillis(),
- RcsPresenceInfo.ServiceState.UNKNOWN, null, System.currentTimeMillis());
- presenceInfoList.add(presenceInfo);
+ // Add each contacts with no capabilities.
+ presenceInfoList.add(new RcsContactUceCapability.Builder(
+ PresenceUtils.convertContactNumber(task.mContacts[i])).build());
}
if(presenceInfoList.size() > 0) {
- // Notify presence information changed.
- logger.debug("notify presence changed for cmd error");
- Intent intent = new Intent(RcsPresence.ACTION_PRESENCE_CHANGED);
- intent.putParcelableArrayListExtra(RcsPresence.EXTRA_PRESENCE_INFO_LIST,
- presenceInfoList);
-
- // don't update timestamp so it can be subscribed soon.
- intent.putExtra("updateLastTimestamp", false);
- launchPersistService(intent);
+ handleCapabilityUpdate(task, presenceInfoList, false);
}
}
}
diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceTask.java b/rcs/rcsservice/src/com/android/service/ims/presence/PresenceTask.java
index ed8afdf..5465e10 100644
--- a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceTask.java
+++ b/rcs/rcsservice/src/com/android/service/ims/presence/PresenceTask.java
@@ -28,34 +28,28 @@
package com.android.service.ims.presence;
-import com.android.ims.IRcsPresenceListener;
-import com.android.ims.internal.Logger;
-import com.android.service.ims.RcsUtils;
import com.android.service.ims.Task;
/**
* PresenceTask
*/
-public class PresenceTask extends Task{
- /*
- * The logger
- */
- private Logger logger = Logger.getLogger(this.getClass().getName());
+public class PresenceTask extends Task {
// filled before send the request to stack
public String[] mContacts;
- public PresenceTask(int taskId, int cmdId, IRcsPresenceListener listener, String[] contacts){
+ public PresenceTask(int taskId, int cmdId, ContactCapabilityResponse listener,
+ String[] contacts){
super(taskId, cmdId, listener);
mContacts = contacts;
mListener = listener;
}
- public String toString(){
+ public String toString() {
return "PresenceTask: mTaskId=" + mTaskId +
" mCmdId=" + mCmdId +
- " mContacts=" + RcsUtils.toContactString(mContacts) +
+ " mContacts=" + PresenceUtils.toContactString(mContacts) +
" mCmdStatus=" + mCmdStatus +
" mSipRequestId=" + mSipRequestId +
" mSipResponseCode=" + mSipResponseCode +
diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceUtils.java b/rcs/rcsservice/src/com/android/service/ims/presence/PresenceUtils.java
new file mode 100644
index 0000000..088f52b
--- /dev/null
+++ b/rcs/rcsservice/src/com/android/service/ims/presence/PresenceUtils.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2019, The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of The Android Open Source Project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+
+package com.android.service.ims.presence;
+
+import android.net.Uri;
+import android.text.TextUtils;
+
+public class PresenceUtils {
+
+ public static final String LOG_TAG_PREFIX = "rcs_lib";
+
+ private static final String TEL_SCHEME = "tel:";
+
+ public static String toContactString(String[] contacts) {
+ if(contacts == null) {
+ return null;
+ }
+
+ String result = "";
+ for(int i=0; i<contacts.length; i++) {
+ result += contacts[i];
+ if(i != contacts.length -1) {
+ result += ";";
+ }
+ }
+
+ return result;
+ }
+
+ public static Uri convertContactNumber(String number) {
+ if (TextUtils.isEmpty(number)) return null;
+ Uri possibleNumber = Uri.parse(number);
+ // already in the correct format
+ if (TEL_SCHEME.equals(possibleNumber.getScheme())) {
+ return possibleNumber;
+ }
+ // need to append tel scheme
+ return Uri.fromParts(TEL_SCHEME, number, null);
+ }
+
+ public static String getNumber(Uri numberUri) {
+ if (numberUri == null) return null;
+ return numberUri.getSchemeSpecificPart();
+ }
+}
diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/SubscribePublisher.java b/rcs/rcsservice/src/com/android/service/ims/presence/SubscribePublisher.java
new file mode 100644
index 0000000..b3eb46d
--- /dev/null
+++ b/rcs/rcsservice/src/com/android/service/ims/presence/SubscribePublisher.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2019, The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of The Android Open Source Project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+
+package com.android.service.ims.presence;
+
+public interface SubscribePublisher {
+
+ /**
+ * Request the Capabilities for the requested contacts associated with a taskId.
+ */
+ int requestCapability(String[] formatedContacts, int taskId);
+
+ /**
+ * Request the Capabilities for the requested contacts associated with a taskId.
+ */
+ int requestAvailability(String formattedContact, int taskId);
+
+ /**
+ * @return the current state of the RCS stack.
+ */
+ int getStackStatusForCapabilityRequest();
+
+ /**==
+ * Notify the stack of the last publish or subscribe request result.
+ */
+ void updatePublisherState(@PresenceBase.PresencePublishState int publishState);
+
+}