aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-02-07 17:54:26 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-02-07 17:54:26 +0000
commitd193fbd550015d567e68090ddc114bb9fb03ea6d (patch)
treec4bb9bf3a5c7c488fb0e2a2aa51f99c5a73df74b
parent4cc06444e27b9a6e775799e11873f3fc75ba70e5 (diff)
parent6e27787a8e84d20c8589dd654d001e4a24318ad4 (diff)
downloadims-d193fbd550015d567e68090ddc114bb9fb03ea6d.tar.gz
Merge "Refactor RcsFEatureManager to be created from TelephonyRcsService" am: 6e27787a8e
Change-Id: I68e0e13482ce0012757d0a9693bef416b7d4f2bf
-rw-r--r--src/java/com/android/ims/FeatureConnector.java23
-rw-r--r--src/java/com/android/ims/IFeatureConnector.java4
-rw-r--r--src/java/com/android/ims/ImsCallbackAdapterManager.java12
-rw-r--r--src/java/com/android/ims/ImsManager.java11
-rw-r--r--src/java/com/android/ims/MmTelFeatureConnection.java14
-rw-r--r--src/java/com/android/ims/RcsFeatureConnection.java195
-rw-r--r--src/java/com/android/ims/RcsFeatureManager.java420
7 files changed, 339 insertions, 340 deletions
diff --git a/src/java/com/android/ims/FeatureConnector.java b/src/java/com/android/ims/FeatureConnector.java
index 2f424842..273dd958 100644
--- a/src/java/com/android/ims/FeatureConnector.java
+++ b/src/java/com/android/ims/FeatureConnector.java
@@ -46,11 +46,6 @@ public class FeatureConnector<T extends IFeatureConnector> extends Handler {
public interface Listener<T> {
/**
- * Check if ImsFeature supported
- */
- boolean isSupported();
-
- /**
* Get ImsFeature manager instance
*/
T getFeatureManager();
@@ -96,14 +91,6 @@ public class FeatureConnector<T extends IFeatureConnector> extends Handler {
}
};
- public FeatureConnector(Context context, int phoneId, Listener<T> listener) {
- mContext = context;
- mPhoneId = phoneId;
- mListener = listener;
- mExecutor = new HandlerExecutor(this);
- mLogPrefix = "?";
- }
-
public FeatureConnector(Context context, int phoneId, Listener<T> listener,
String logPrefix) {
mContext = context;
@@ -157,7 +144,7 @@ public class FeatureConnector<T extends IFeatureConnector> extends Handler {
// Check if this ImsFeature is supported or not.
private boolean isSupported() {
- return mListener.isSupported();
+ return ImsManager.isImsSupportedOnDevice(mContext);
}
/**
@@ -178,18 +165,18 @@ public class FeatureConnector<T extends IFeatureConnector> extends Handler {
private final Runnable mGetServiceRunnable = () -> {
try {
createImsService();
- } catch (ImsException e) {
+ } catch (android.telephony.ims.ImsException e) {
int errorCode = e.getCode();
if (DBG) logw("Create IMS service error: " + errorCode);
- if (ImsReasonInfo.CODE_LOCAL_IMS_NOT_SUPPORTED_ON_DEVICE != errorCode) {
- // Retry when error is not IMS_NOT_SUPPORTED_ON_DEVICE
+ if (android.telephony.ims.ImsException.CODE_ERROR_UNSUPPORTED_OPERATION != errorCode) {
+ // Retry when error is not CODE_ERROR_UNSUPPORTED_OPERATION
retryGetImsService();
}
}
};
@VisibleForTesting
- public void createImsService() throws ImsException {
+ public void createImsService() throws android.telephony.ims.ImsException {
synchronized (mLock) {
if (DBG) log("createImsService");
mManager = mListener.getFeatureManager();
diff --git a/src/java/com/android/ims/IFeatureConnector.java b/src/java/com/android/ims/IFeatureConnector.java
index a169bb23..66428ce7 100644
--- a/src/java/com/android/ims/IFeatureConnector.java
+++ b/src/java/com/android/ims/IFeatureConnector.java
@@ -16,9 +16,9 @@
package com.android.ims;
-public interface IFeatureConnector {
+public interface IFeatureConnector<T> {
int getImsServiceState() throws ImsException;
void addNotifyStatusChangedCallbackIfAvailable(FeatureConnection.IFeatureUpdate callback)
- throws ImsException;
+ throws android.telephony.ims.ImsException;
void removeNotifyStatusChangedCallback(FeatureConnection.IFeatureUpdate callback);
} \ No newline at end of file
diff --git a/src/java/com/android/ims/ImsCallbackAdapterManager.java b/src/java/com/android/ims/ImsCallbackAdapterManager.java
index bf2bd39d..d4926b2f 100644
--- a/src/java/com/android/ims/ImsCallbackAdapterManager.java
+++ b/src/java/com/android/ims/ImsCallbackAdapterManager.java
@@ -35,7 +35,7 @@ import java.util.Set;
import java.util.stream.Collectors;
public abstract class ImsCallbackAdapterManager<T extends IInterface> {
- private static final String TAG = "ImsCallbackAdapterManager";
+ private static final String TAG = "ImsCallbackAM";
private final Context mContext;
private final Object mLock;
@@ -98,8 +98,8 @@ public abstract class ImsCallbackAdapterManager<T extends IInterface> {
};
}
- // Add a callback to the MmTelFeature associated with this manager (independent of the)
- // current subscription.
+ // Add a callback to the ImsFeature associated with this manager (independent of the
+ // current subscription).
public final void addCallback(T localCallback) {
synchronized (mLock) {
// Skip registering to callback subscription map here, because we are registering
@@ -124,7 +124,7 @@ public abstract class ImsCallbackAdapterManager<T extends IInterface> {
}
}
- // Removes a callback associated with the MmTelFeature.
+ // Removes a callback associated with the ImsFeature.
public final void removeCallback(T localCallback) {
Log.i(TAG + " [" + mSlotId + "]", "Local callback removed: " + localCallback);
synchronized (mLock) {
@@ -255,9 +255,9 @@ public abstract class ImsCallbackAdapterManager<T extends IInterface> {
}
}
- // A callback has been registered. Register that callback with the MmTelFeature.
+ // A callback has been registered. Register that callback with the ImsFeature.
public abstract void registerCallback(T localCallback);
- // A callback has been removed, unregister that callback with the MmTelFeature.
+ // A callback has been removed, unregister that callback with the RcsFeature.
public abstract void unregisterCallback(T localCallback);
}
diff --git a/src/java/com/android/ims/ImsManager.java b/src/java/com/android/ims/ImsManager.java
index 39d9e503..2e696ba7 100644
--- a/src/java/com/android/ims/ImsManager.java
+++ b/src/java/com/android/ims/ImsManager.java
@@ -1557,10 +1557,10 @@ public class ImsManager implements IFeatureConnector {
@Override
@VisibleForTesting
public void addNotifyStatusChangedCallbackIfAvailable(FeatureConnection.IFeatureUpdate c)
- throws ImsException {
+ throws android.telephony.ims.ImsException {
if (!mMmTelFeatureConnection.isBinderAlive()) {
- throw new ImsException("Binder is not active!",
- ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
+ throw new android.telephony.ims.ImsException("Can not connect to ImsService",
+ android.telephony.ims.ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
}
if (c != null) {
mStatusCallbacks.add(c);
@@ -2277,10 +2277,7 @@ public class ImsManager implements IFeatureConnector {
}
/**
- * Binds the IMS service to make/receive the call. Supports two methods of exposing an
- * ImsService:
- * 1) com.android.ims.ImsService implementation in ServiceManager (deprecated).
- * 2) android.telephony.ims.ImsService implementation through ImsResolver.
+ * Creates a connection to the ImsService associated with this slot.
*/
private void createImsService() {
mMmTelFeatureConnection = MmTelFeatureConnection.create(mContext, mPhoneId);
diff --git a/src/java/com/android/ims/MmTelFeatureConnection.java b/src/java/com/android/ims/MmTelFeatureConnection.java
index 2c10a238..40075bcb 100644
--- a/src/java/com/android/ims/MmTelFeatureConnection.java
+++ b/src/java/com/android/ims/MmTelFeatureConnection.java
@@ -240,21 +240,11 @@ public class MmTelFeatureConnection extends FeatureConnection {
@Override
protected void onRemovedOrDied() {
synchronized (mLock) {
+ super.onRemovedOrDied();
mRegistrationCallbackManager.close();
mCapabilityCallbackManager.close();
mProvisioningCallbackManager.close();
- if (mIsAvailable) {
- mIsAvailable = false;
- // invalidate caches.
- mRegistrationBinder = null;
- mConfigBinder = null;
- if (mBinder != null) {
- mBinder.unlinkToDeath(mDeathRecipient, 0);
- }
- if (mStatusCallback != null) {
- mStatusCallback.notifyUnavailable();
- }
- }
+ mConfigBinder = null;
}
}
diff --git a/src/java/com/android/ims/RcsFeatureConnection.java b/src/java/com/android/ims/RcsFeatureConnection.java
index ea09e6fd..daee6dd6 100644
--- a/src/java/com/android/ims/RcsFeatureConnection.java
+++ b/src/java/com/android/ims/RcsFeatureConnection.java
@@ -21,32 +21,90 @@ import android.content.Context;
import android.os.IBinder;
import android.os.RemoteException;
import android.telephony.TelephonyManager;
-import android.telephony.ims.RcsContactUceCapability;
import android.telephony.ims.aidl.IImsCapabilityCallback;
import android.telephony.ims.aidl.IImsRcsFeature;
+import android.telephony.ims.aidl.IImsRegistration;
+import android.telephony.ims.aidl.IImsRegistrationCallback;
import android.telephony.ims.aidl.IRcsFeatureListener;
import android.telephony.ims.feature.CapabilityChangeRequest;
import android.telephony.ims.feature.ImsFeature;
-import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.service.ims.presence.PresencePublisher;
-import com.android.service.ims.presence.SubscribePublisher;
import com.android.telephony.Rlog;
/**
* A container of the IImsServiceController binder, which implements all of the RcsFeatures that
* the platform currently supports: RCS
*/
-public class RcsFeatureConnection extends FeatureConnection implements PresencePublisher,
- SubscribePublisher {
+public class RcsFeatureConnection extends FeatureConnection {
private static final String TAG = "RcsFeatureConnection";
- public interface IRcsFeatureUpdate extends IFeatureUpdate {
- /**
- * Called when the ImsFeature has been created.
- */
- void notifyFeatureCreated();
+ public class AvailabilityCallbackManager extends
+ ImsCallbackAdapterManager<IImsCapabilityCallback> {
+
+ AvailabilityCallbackManager(Context context) {
+ super(context, new Object() /* Lock object */, mSlotId);
+ }
+
+ @Override
+ public void registerCallback(IImsCapabilityCallback localCallback) {
+ try {
+ addCapabilityCallback(localCallback);
+ } catch (RemoteException e) {
+ loge("Register capability callback error: " + e);
+ throw new IllegalStateException(
+ " CapabilityCallbackManager: Register callback error");
+ }
+ }
+
+ @Override
+ public void unregisterCallback(IImsCapabilityCallback localCallback) {
+ try {
+ removeCapabilityCallback(localCallback);
+ } catch (RemoteException e) {
+ loge("Cannot remove capability callback: " + e);
+ }
+ }
+ }
+
+ private class RegistrationCallbackManager extends
+ ImsCallbackAdapterManager<IImsRegistrationCallback> {
+
+ public RegistrationCallbackManager(Context context) {
+ super(context, new Object() /* Lock object */, mSlotId);
+ }
+
+ @Override
+ public void registerCallback(IImsRegistrationCallback localCallback) {
+ IImsRegistration imsRegistration = getRegistration();
+ if (imsRegistration == null) {
+ loge("Register IMS registration callback: ImsRegistration is null");
+ throw new IllegalStateException("RegistrationCallbackAdapter: RcsFeature is"
+ + " not available!");
+ }
+
+ try {
+ imsRegistration.addRegistrationCallback(localCallback);
+ } catch (RemoteException e) {
+ throw new IllegalStateException("RegistrationCallbackAdapter: RcsFeature"
+ + " binder is dead.");
+ }
+ }
+
+ @Override
+ public void unregisterCallback(IImsRegistrationCallback localCallback) {
+ IImsRegistration imsRegistration = getRegistration();
+ if (imsRegistration == null) {
+ logi("Unregister IMS registration callback: ImsRegistration is null");
+ return;
+ }
+
+ try {
+ imsRegistration.removeRegistrationCallback(localCallback);
+ } catch (RemoteException e) {
+ loge("Cannot remove registration callback: " + e);
+ }
+ }
}
public static @NonNull RcsFeatureConnection create(Context context , int slotId,
@@ -83,51 +141,55 @@ public class RcsFeatureConnection extends FeatureConnection implements PresenceP
}
@VisibleForTesting
- public IRcsFeatureUpdate mRcsFeatureStatusCallback;
+ public AvailabilityCallbackManager mAvailabilityCallbackManager;
+ @VisibleForTesting
+ public RegistrationCallbackManager mRegistrationCallbackManager;
private RcsFeatureConnection(Context context, int slotId, IFeatureUpdate callback) {
super(context, slotId, ImsFeature.FEATURE_RCS);
setStatusCallback(callback);
+ mAvailabilityCallbackManager = new AvailabilityCallbackManager(mContext);
+ mRegistrationCallbackManager = new RegistrationCallbackManager(mContext);
}
public void close() {
removeRcsFeatureListener();
+ mAvailabilityCallbackManager.close();
+ mRegistrationCallbackManager.close();
}
@Override
- public void setStatusCallback(IFeatureUpdate callback) {
- super.setStatusCallback(callback);
- mRcsFeatureStatusCallback = (IRcsFeatureUpdate) mStatusCallback;
+ protected void onRemovedOrDied() {
+ super.onRemovedOrDied();
+ synchronized (mLock) {
+ close();
+ }
}
@Override
@VisibleForTesting
public void handleImsFeatureCreatedCallback(int slotId, int feature) {
- Log.i(TAG, "IMS feature created: slotId= " + slotId + ", feature=" + feature);
+ logi("IMS feature created: slotId= " + slotId + ", feature=" + feature);
if (!isUpdateForThisFeatureAndSlot(slotId, feature)) {
return;
}
synchronized(mLock) {
if (!mIsAvailable) {
- Log.i(TAG, "RCS enabled on slotId: " + slotId);
+ logi("RCS enabled on slotId: " + slotId);
mIsAvailable = true;
}
- // Notify RcsFeatureManager that RCS feature has already been created
- if (mRcsFeatureStatusCallback != null) {
- mRcsFeatureStatusCallback.notifyFeatureCreated();
- }
}
}
@Override
@VisibleForTesting
public void handleImsFeatureRemovedCallback(int slotId, int feature) {
- Log.i(TAG, "IMS feature removed: slotId= " + slotId + ", feature=" + feature);
+ logi("IMS feature removed: slotId= " + slotId + ", feature=" + feature);
if (!isUpdateForThisFeatureAndSlot(slotId, feature)) {
return;
}
synchronized(mLock) {
- Log.i(TAG, "Rcs UCE removed on slotId: " + slotId);
+ logi("Rcs UCE removed on slotId: " + slotId);
onRemovedOrDied();
}
}
@@ -135,17 +197,13 @@ public class RcsFeatureConnection extends FeatureConnection implements PresenceP
@Override
@VisibleForTesting
public void handleImsStatusChangedCallback(int slotId, int feature, int status) {
- Log.i(TAG, "IMS status changed: slotId=" + slotId
- + ", feature=" + feature + ", status=" + status);
+ logi("IMS status changed: slotId=" + slotId + ", feature=" + feature + ", status="
+ + status);
if (!isUpdateForThisFeatureAndSlot(slotId, feature)) {
return;
}
synchronized(mLock) {
mFeatureStateCached = status;
- // notify RCS feature status changed
- if (mRcsFeatureStatusCallback != null) {
- mRcsFeatureStatusCallback.notifyStateChanged();
- }
}
}
@@ -167,6 +225,7 @@ public class RcsFeatureConnection extends FeatureConnection implements PresenceP
try {
setRcsFeatureListener(null);
} catch (RemoteException e) {
+ // If we are not still connected, there is no need to fail removing.
}
}
@@ -177,14 +236,40 @@ public class RcsFeatureConnection extends FeatureConnection implements PresenceP
}
}
- public void addCapabilityCallback(IImsCapabilityCallback callback) throws RemoteException {
+ public void addCallbackForSubscription(int subId, IImsCapabilityCallback cb) {
+ mAvailabilityCallbackManager.addCallbackForSubscription(cb, subId);
+ }
+
+ public void addCallbackForSubscription(int subId, IImsRegistrationCallback cb) {
+ mRegistrationCallbackManager.addCallbackForSubscription(cb, subId);
+ }
+
+ public void addCallback(IImsRegistrationCallback cb) {
+ mRegistrationCallbackManager.addCallback(cb);
+ }
+
+ public void removeCallbackForSubscription(int subId, IImsCapabilityCallback cb) {
+ mAvailabilityCallbackManager.removeCallbackForSubscription(cb, subId);
+ }
+
+ public void removeCallbackForSubscription(int subId, IImsRegistrationCallback cb) {
+ mRegistrationCallbackManager.removeCallbackForSubscription(cb, subId);
+ }
+
+ public void removeCallback(IImsRegistrationCallback cb) {
+ mRegistrationCallbackManager.removeCallback(cb);
+ }
+
+ // Add callback to remote service
+ private void addCapabilityCallback(IImsCapabilityCallback callback) throws RemoteException {
synchronized (mLock) {
checkServiceIsReady();
getServiceInterface(mBinder).addCapabilityCallback(callback);
}
}
- public void removeCapabilityCallback(IImsCapabilityCallback callback) throws RemoteException {
+ // Remove callback to remote service
+ private void removeCapabilityCallback(IImsCapabilityCallback callback) throws RemoteException {
synchronized (mLock) {
checkServiceIsReady();
getServiceInterface(mBinder).removeCapabilityCallback(callback);
@@ -208,43 +293,6 @@ public class RcsFeatureConnection extends FeatureConnection implements PresenceP
}
@Override
- public int getPublisherState() {
- // Need to implement this api
- throw new UnsupportedOperationException();
- }
-
- @Override
- public int requestPublication(RcsContactUceCapability capabilities, String contactUri,
- int taskId) {
- // Need to implement this api
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void updatePublisherState(int publishState) {
- // Need to implement this api
- throw new UnsupportedOperationException();
- }
-
- @Override
- public int requestCapability(String[] formattedContacts, int taskId) {
- // Need to implement this api
- throw new UnsupportedOperationException();
- }
-
- @Override
- public int requestAvailability(String formattedContact, int taskId) {
- // Need to implement this api
- throw new UnsupportedOperationException();
- }
-
- @Override
- public int getStackStatusForCapabilityRequest() {
- // Need to implement this api
- throw new UnsupportedOperationException();
- }
-
- @Override
@VisibleForTesting
public Integer retrieveFeatureState() {
if (mBinder != null) {
@@ -261,4 +309,15 @@ public class RcsFeatureConnection extends FeatureConnection implements PresenceP
public IImsRcsFeature getServiceInterface(IBinder b) {
return IImsRcsFeature.Stub.asInterface(b);
}
+ private void log(String s) {
+ Rlog.d(TAG + " [" + mSlotId + "]", s);
+ }
+
+ private void logi(String s) {
+ Rlog.i(TAG + " [" + mSlotId + "]", s);
+ }
+
+ private void loge(String s) {
+ Rlog.e(TAG + " [" + mSlotId + "]", s);
+ }
}
diff --git a/src/java/com/android/ims/RcsFeatureManager.java b/src/java/com/android/ims/RcsFeatureManager.java
index 1d8e6f1c..3fe92129 100644
--- a/src/java/com/android/ims/RcsFeatureManager.java
+++ b/src/java/com/android/ims/RcsFeatureManager.java
@@ -16,27 +16,27 @@
package com.android.ims;
-import android.annotation.Nullable;
import android.content.Context;
import android.net.Uri;
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
-import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.RcsContactUceCapability;
+import android.telephony.ims.RegistrationManager;
import android.telephony.ims.aidl.IImsCapabilityCallback;
-import android.telephony.ims.aidl.IImsRegistration;
import android.telephony.ims.aidl.IImsRegistrationCallback;
import android.telephony.ims.aidl.IRcsFeatureListener;
import android.telephony.ims.feature.CapabilityChangeRequest;
+import android.telephony.ims.feature.RcsFeature;
import android.telephony.ims.feature.RcsFeature.RcsImsCapabilities;
import android.telephony.ims.stub.ImsRegistrationImplBase;
+import android.telephony.ims.stub.RcsCapabilityExchange;
import android.telephony.ims.stub.RcsPresenceExchangeImplBase;
+import android.telephony.ims.stub.RcsSipOptionsImplBase;
import android.util.Log;
import com.android.ims.FeatureConnection.IFeatureUpdate;
-import com.android.ims.RcsFeatureConnection.IRcsFeatureUpdate;
import com.android.internal.annotations.VisibleForTesting;
import com.android.telephony.Rlog;
@@ -47,6 +47,12 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
+/**
+ * Encapsulates all logic related to the RcsFeature:
+ * - Updating RcsFeature capabilities.
+ * - Registering/Unregistering availability/registration callbacks.
+ * - Querying Registration and Capability information.
+ */
public class RcsFeatureManager implements IFeatureConnector {
private static final String TAG = "RcsFeatureManager";
private static boolean DBG = true;
@@ -54,47 +60,109 @@ public class RcsFeatureManager implements IFeatureConnector {
private static final int CAPABILITY_OPTIONS = RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE;
private static final int CAPABILITY_PRESENCE = RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE;
+ /**
+ * Callbacks from the RcsFeature, which have an empty default implementation and can be
+ * overridden for each Feature.
+ */
+ public static class RcsFeatureCallbacks {
+ /** See {@link RcsCapabilityExchange#onCommandUpdate(int, int)} */
+ void onCommandUpdate(int commandCode, int operationToken) {}
+
+ /** See {@link RcsPresenceExchangeImplBase#onNetworkResponse(int, String, int)} */
+ public void onNetworkResponse(int code, String reason, int operationToken) {}
+
+ /** See {@link RcsPresenceExchangeImplBase#onCapabilityRequestResponse(List, int)} */
+ public void onCapabilityRequestResponsePresence(List<RcsContactUceCapability> infos,
+ int operationToken) {}
+
+ /** See {@link RcsPresenceExchangeImplBase#onNotifyUpdateCapabilites(int)} */
+ public void onNotifyUpdateCapabilities(int publishTriggerType) {}
+
+ /** See {@link RcsPresenceExchangeImplBase#onUnpublish()} */
+ public void onUnpublish() {}
+
+ /**
+ * See {@link RcsSipOptionsImplBase#onCapabilityRequestResponse(int,String,
+ * RcsContactUceCapability, int)}
+ */
+ public void onCapabilityRequestResponseOptions(int code, String reason,
+ RcsContactUceCapability info, int operationToken) {}
+
+ /**
+ * See {@link RcsSipOptionsImplBase#onRemoteCapabilityRequest(Uri, RcsContactUceCapability,
+ * int)}
+ */
+ public void onRemoteCapabilityRequest(Uri contactUri, RcsContactUceCapability remoteInfo,
+ int operationToken) {}
+ }
+
+ private final IRcsFeatureListener mRcsFeatureCallbackAdapter = new IRcsFeatureListener.Stub() {
+ @Override
+ public void onCommandUpdate(int commandCode, int operationToken) {
+ mRcsFeatureCallbacks.forEach(listener-> listener.onCommandUpdate(commandCode,
+ operationToken));
+ }
+
+ @Override
+ public void onNetworkResponse(int code, String reason, int operationToken) {
+ mRcsFeatureCallbacks.forEach(listener-> listener.onNetworkResponse(code, reason,
+ operationToken));
+ }
+
+ @Override
+ public void onCapabilityRequestResponsePresence(List<RcsContactUceCapability> infos,
+ int operationToken) {
+ mRcsFeatureCallbacks.forEach(listener-> listener.onCapabilityRequestResponsePresence(
+ infos, operationToken));
+ }
+
+ @Override
+ public void onNotifyUpdateCapabilities(int publishTriggerType) {
+ mRcsFeatureCallbacks.forEach(listener-> listener.onNotifyUpdateCapabilities(
+ publishTriggerType));
+ }
+
+ @Override
+ public void onUnpublish() {
+ mRcsFeatureCallbacks.forEach(listener-> listener.onUnpublish());
+ }
+
+ @Override
+ public void onCapabilityRequestResponseOptions(int code, String reason,
+ RcsContactUceCapability info, int operationToken) {
+ mRcsFeatureCallbacks.forEach(listener -> listener.onCapabilityRequestResponseOptions(
+ code, reason, info, operationToken));
+ }
+
+ @Override
+ public void onRemoteCapabilityRequest(Uri contactUri, RcsContactUceCapability remoteInfo,
+ int operationToken) {
+ mRcsFeatureCallbacks.forEach(listener -> listener.onRemoteCapabilityRequest(
+ contactUri, remoteInfo, operationToken));
+ }
+ };
+
private final int mSlotId;
private final Context mContext;
+ @VisibleForTesting
+ public final Set<IFeatureUpdate> mStatusCallbacks = new CopyOnWriteArraySet<>();
+ private final Set<RcsFeatureCallbacks> mRcsFeatureCallbacks = new CopyOnWriteArraySet<>();
@VisibleForTesting
public RcsFeatureConnection mRcsFeatureConnection;
- @VisibleForTesting
- public RcsCapabilityCallbackManager mCapabilityCallbackManager;
- @VisibleForTesting
- public ImsRegistrationCallbackAdapter mRegistrationCallbackManager;
- @VisibleForTesting
- public Set<IFeatureUpdate> mStatusCallbacks = new CopyOnWriteArraySet<>();
public RcsFeatureManager(Context context, int slotId) {
mContext = context;
mSlotId = slotId;
logi("RcsFeatureManager");
- mCapabilityCallbackManager = new RcsCapabilityCallbackManager(context);
- mRegistrationCallbackManager = new ImsRegistrationCallbackAdapter(context);
-
createImsService();
}
- public void release() {
- logi("release");
- mStatusCallbacks.clear();
- mCapabilityCallbackManager.close();
- mRegistrationCallbackManager.close();
- mRcsFeatureConnection.close();
- }
-
// Binds the IMS service to the RcsFeature instance.
private void createImsService() {
mRcsFeatureConnection = RcsFeatureConnection.create(mContext, mSlotId,
- new IRcsFeatureUpdate() {
- @Override
- public void notifyFeatureCreated() {
- logi("RcsFeature is created");
- setRcsFeatureListener();
- updateCapabilities();
- }
+ new IFeatureUpdate() {
@Override
public void notifyStateChanged() {
mStatusCallbacks.forEach(
@@ -110,148 +178,100 @@ public class RcsFeatureManager implements IFeatureConnector {
}
/**
- * Set RcsFeature listener and it will also trigger onFeatureReady in RcsFeature.
+ * Opens a persistent connection to the RcsFeature. This must be called before the RcsFeature
+ * can be used to communicate. Triggers a {@link RcsFeature#onFeatureReady()} call on the
+ * service side.
*/
- private void setRcsFeatureListener() {
- if (DBG) log("Set RcsFeature listener");
+ public void openConnection() throws android.telephony.ims.ImsException {
try {
- mRcsFeatureConnection.setRcsFeatureListener(mRcsFeatureListener);
- } catch (RemoteException e) {
- loge("setRcsFeatureListener: ", e);
+ mRcsFeatureConnection.setRcsFeatureListener(mRcsFeatureCallbackAdapter);
+ } catch (RemoteException e){
+ throw new android.telephony.ims.ImsException("Service is not available.",
+ android.telephony.ims.ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
}
}
/**
- * Update current UCE capabilities.
+ * Closes the persistent connection to the RcsFeature. This must be called when this manager
+ * wishes to no longer be used to communicate with the RcsFeature.
*/
- @VisibleForTesting
- public void updateCapabilities() {
+ public void releaseConnection() {
+ try {
+ mRcsFeatureConnection.setRcsFeatureListener(null);
+ } catch (RemoteException e){
+ // Connection may not be available at this point.
+ }
+ mStatusCallbacks.clear();
+ mRcsFeatureConnection.close();
+ mRcsFeatureCallbacks.clear();
+ }
+
+ /**
+ * Adds a callback for {@link RcsFeatureCallbacks}.
+ * Note: These callbacks will be sent on the binder thread used to notify the callback.
+ */
+ public void addFeatureListenerCallback(RcsFeatureCallbacks listener) {
+ mRcsFeatureCallbacks.add(listener);
+ }
+
+ /**
+ * Removes an existing {@link RcsFeatureCallbacks}.
+ */
+ public void removeFeatureListenerCallback(RcsFeatureCallbacks listener) {
+ mRcsFeatureCallbacks.remove(listener);
+ }
+
+ /**
+ * Update the capabilities for this RcsFeature.
+ */
+ public void updateCapabilities() throws android.telephony.ims.ImsException {
boolean optionsSupport = isOptionsSupported();
boolean presenceSupported = isPresenceSupported();
- if (DBG) log("Update capabilities: options=" + optionsSupport
+ logi("Update capabilities for slot " + mSlotId + ": options=" + optionsSupport
+ ", presence=" + presenceSupported);
if (optionsSupport || presenceSupported) {
+ CapabilityChangeRequest request = new CapabilityChangeRequest();
if (optionsSupport) {
- enableRcsUceCapability(CAPABILITY_OPTIONS);
+ addRcsUceCapability(request, CAPABILITY_OPTIONS);
}
if (presenceSupported) {
- enableRcsUceCapability(CAPABILITY_PRESENCE);
+ addRcsUceCapability(request, CAPABILITY_PRESENCE);
}
+ sendCapabilityChangeRequest(request);
} else {
disableAllRcsUceCapabilities();
}
}
- public RcsFeatureConnection getRcsFeatureConnection() {
- return mRcsFeatureConnection;
- }
-
/**
- * The callback to receive updated from RcsFeature
- */
- protected IRcsFeatureListener mRcsFeatureListener = new IRcsFeatureListener.Stub() {
- @Override
- public void onCommandUpdate(int commandCode, int operationToken) {
- }
-
- @Override
- public void onNetworkResponse(int code, String reason, int operationToken) {
- }
-
- @Override
- public void onCapabilityRequestResponsePresence(
- List<RcsContactUceCapability> infos, int operationToken) {
- }
-
- @Override
- public void onNotifyUpdateCapabilities(
- @RcsPresenceExchangeImplBase.StackPublishTriggerType int triggerType) {
- }
-
- @Override
- public void onUnpublish() {
- }
-
- @Override
- public void onCapabilityRequestResponseOptions(
- int code, String reason, RcsContactUceCapability info, int operationToken) {
- }
-
- @Override
- public void onRemoteCapabilityRequest(
- Uri contactUri, RcsContactUceCapability remoteInfo, int operationToken) {
- }
- };
-
- /**
- * A inner class to manager all the ImsRegistrationCallback associated with RcsFeature.
+ * Add a {@link RegistrationManager.RegistrationCallback} callback that gets called when IMS
+ * registration has changed for a specific subscription.
*/
- private class ImsRegistrationCallbackAdapter extends
- ImsCallbackAdapterManager<IImsRegistrationCallback> {
-
- public ImsRegistrationCallbackAdapter(Context context) {
- super(context, new Object() /* Lock object */, mSlotId);
- }
-
- @Override
- public void registerCallback(IImsRegistrationCallback localCallback) {
- if (DBG) log("Register IMS registration callback");
-
- IImsRegistration imsRegistration = getRegistration();
- if (imsRegistration == null) {
- loge("Register IMS registration callback: ImsRegistration is null");
- throw new IllegalStateException("ImsRegistrationCallbackAdapter: RcsFeature is"
- + " not available!");
- }
-
- try {
- imsRegistration.addRegistrationCallback(localCallback);
- } catch (RemoteException e) {
- throw new IllegalStateException("ImsRegistrationCallbackAdapter: RcsFeature"
- + " binder is dead.");
- }
- }
-
- @Override
- public void unregisterCallback(IImsRegistrationCallback localCallback) {
- if (DBG) log("Unregister IMS registration callback");
-
- IImsRegistration imsRegistration = getRegistration();
- if (imsRegistration == null) {
- log("Unregister IMS registration callback: ImsRegistration is null");
- return;
- }
-
- try {
- imsRegistration.removeRegistrationCallback(localCallback);
- } catch (RemoteException e) {
- loge("Cannot remove registration callback: " + e);
- }
- }
-
- private @Nullable IImsRegistration getRegistration() {
- if (mRcsFeatureConnection == null) {
- return null;
- }
- return mRcsFeatureConnection.getRegistration();
+ public void registerImsRegistrationCallback(int subId, IImsRegistrationCallback callback)
+ throws android.telephony.ims.ImsException {
+ try {
+ mRcsFeatureConnection.addCallbackForSubscription(subId, callback);
+ } catch (IllegalStateException e) {
+ loge("registerImsRegistrationCallback error: ", e);
+ throw new android.telephony.ims.ImsException("Can not register callback",
+ android.telephony.ims.ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
}
}
/**
* Add a {@link RegistrationManager.RegistrationCallback} callback that gets called when IMS
- * registration has changed for a specific subscription.
+ * registration has changed, independent of the subscription it is currently on.
*/
public void registerImsRegistrationCallback(IImsRegistrationCallback callback)
- throws ImsException {
+ throws android.telephony.ims.ImsException {
try {
- int subId = sSubscriptionManagerProxy.getSubId(mSlotId);
- mRegistrationCallbackManager.addCallbackForSubscription(callback, subId);
+ mRcsFeatureConnection.addCallback(callback);
} catch (IllegalStateException e) {
loge("registerImsRegistrationCallback error: ", e);
- throw new ImsException(
- "register registration callback", e, ImsReasonInfo.CODE_LOCAL_INTERNAL_ERROR);
+ throw new android.telephony.ims.ImsException("Can not register callback",
+ android.telephony.ims.ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
}
}
@@ -259,13 +279,16 @@ public class RcsFeatureManager implements IFeatureConnector {
* Removes a previously registered {@link RegistrationManager.RegistrationCallback} callback
* that is associated with a specific subscription.
*/
+ public void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback callback) {
+ mRcsFeatureConnection.removeCallbackForSubscription(subId, callback);
+ }
+
+ /**
+ * Removes a previously registered {@link RegistrationManager.RegistrationCallback} callback
+ * that was not associated with a subscription.
+ */
public void unregisterImsRegistrationCallback(IImsRegistrationCallback callback) {
- try {
- int subId = sSubscriptionManagerProxy.getSubId(mSlotId);
- mRegistrationCallbackManager.removeCallbackForSubscription(callback, subId);
- } catch (IllegalStateException e) {
- loge("unregisterImsRegistrationCallback error: ", e);
- }
+ mRcsFeatureConnection.removeCallback(callback);
}
/**
@@ -283,68 +306,25 @@ public class RcsFeatureManager implements IFeatureConnector {
}
/**
- * A inner class to manager all the ImsCapabilityCallbacks associated with RcsFeature.
- */
- @VisibleForTesting
- public class RcsCapabilityCallbackManager extends
- ImsCallbackAdapterManager<IImsCapabilityCallback> {
-
- RcsCapabilityCallbackManager(Context context) {
- super(context, new Object() /* Lock object */, mSlotId);
- }
-
- @Override
- public void registerCallback(IImsCapabilityCallback localCallback) {
- if (DBG) log("Register capability callback");
- try {
- mRcsFeatureConnection.addCapabilityCallback(localCallback);
- } catch (RemoteException e) {
- loge("Register capability callback error: " + e);
- throw new IllegalStateException(
- " CapabilityCallbackManager: Register callback error");
- }
- }
-
- @Override
- public void unregisterCallback(IImsCapabilityCallback localCallback) {
- if (DBG) log("Unregister capability callback");
- try {
- mRcsFeatureConnection.removeCapabilityCallback(localCallback);
- } catch (RemoteException e) {
- loge("Cannot remove capability callback: " + e);
- }
- }
- }
-
- /**
* Register an ImsCapabilityCallback with RCS service, which will provide RCS availability
* updates.
*/
- public void registerRcsAvailabilityCallback(IImsCapabilityCallback callback)
- throws ImsException {
+ public void registerRcsAvailabilityCallback(int subId, IImsCapabilityCallback callback)
+ throws android.telephony.ims.ImsException {
try {
- int subId = sSubscriptionManagerProxy.getSubId(mSlotId);
- mCapabilityCallbackManager.addCallbackForSubscription(callback, subId);
+ mRcsFeatureConnection.addCallbackForSubscription(subId, callback);
} catch (IllegalStateException e) {
loge("registerRcsAvailabilityCallback: ", e);
- throw new ImsException(
- "register capability callback", e, ImsReasonInfo.CODE_LOCAL_INTERNAL_ERROR);
+ throw new android.telephony.ims.ImsException("Can not register callback",
+ android.telephony.ims.ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
}
}
/**
* Remove an registered ImsCapabilityCallback from RCS service.
*/
- public void unregisterRcsAvailabilityCallback(IImsCapabilityCallback callback)
- throws ImsException {
- try {
- int subId = sSubscriptionManagerProxy.getSubId(mSlotId);
- mCapabilityCallbackManager.removeCallbackForSubscription(callback, subId);
- } catch (IllegalStateException e) {
- loge("unregisterRcsAvailabilityCallback: ", e);
- throw new ImsException(
- "unregister capability callback", e, ImsReasonInfo.CODE_LOCAL_INTERNAL_ERROR);
- }
+ public void unregisterRcsAvailabilityCallback(int subId, IImsCapabilityCallback callback) {
+ mRcsFeatureConnection.removeCallbackForSubscription(subId, callback);
}
/**
@@ -352,7 +332,8 @@ public class RcsFeatureManager implements IFeatureConnector {
*/
public boolean isCapable(
@RcsImsCapabilities.RcsImsCapabilityFlag int capability,
- @ImsRegistrationImplBase.ImsRegistrationTech int radioTech) throws ImsException {
+ @ImsRegistrationImplBase.ImsRegistrationTech int radioTech)
+ throws android.telephony.ims.ImsException {
CountDownLatch latch = new CountDownLatch(1);
AtomicReference<Boolean> capableRef = new AtomicReference<>();
@@ -386,7 +367,8 @@ public class RcsFeatureManager implements IFeatureConnector {
return awaitResult(latch, capableRef);
} catch (RemoteException e) {
loge("isCapable error: ", e);
- throw new ImsException("is capable", e, ImsReasonInfo.CODE_LOCAL_INTERNAL_ERROR);
+ throw new android.telephony.ims.ImsException("Can not determine capabilities",
+ android.telephony.ims.ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
}
}
@@ -403,13 +385,14 @@ public class RcsFeatureManager implements IFeatureConnector {
* Query the availability of an IMS RCS capability.
*/
public boolean isAvailable(@RcsImsCapabilities.RcsImsCapabilityFlag int capability)
- throws ImsException {
+ throws android.telephony.ims.ImsException {
try {
int currentStatus = mRcsFeatureConnection.queryCapabilityStatus();
return new RcsImsCapabilities(currentStatus).isCapable(capability);
} catch (RemoteException e) {
loge("isAvailable error: ", e);
- throw new ImsException("is RCS available", e, ImsReasonInfo.CODE_LOCAL_INTERNAL_ERROR);
+ throw new android.telephony.ims.ImsException("Can not determine availability",
+ android.telephony.ims.ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
}
}
@@ -419,10 +402,10 @@ public class RcsFeatureManager implements IFeatureConnector {
*/
@Override
public void addNotifyStatusChangedCallbackIfAvailable(FeatureConnection.IFeatureUpdate c)
- throws ImsException {
+ throws android.telephony.ims.ImsException {
if (!mRcsFeatureConnection.isBinderAlive()) {
- throw new ImsException("Binder is not active!",
- ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
+ throw new android.telephony.ims.ImsException("Can not connect to service.",
+ android.telephony.ims.ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
}
if (c != null) {
mStatusCallbacks.add(c);
@@ -437,29 +420,21 @@ public class RcsFeatureManager implements IFeatureConnector {
}
/**
- * Enable UCE capabilities with given type.
+ * Add UCE capabilities with given type.
* @param capability the specific RCS UCE capability wants to enable
*/
- public void enableRcsUceCapability(
+ public void addRcsUceCapability(CapabilityChangeRequest request,
@RcsImsCapabilities.RcsImsCapabilityFlag int capability) {
-
- CapabilityChangeRequest request = new CapabilityChangeRequest();
request.addCapabilitiesToEnableForTech(capability,
ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
request.addCapabilitiesToEnableForTech(capability,
ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN);
- try {
- if (DBG) log("enableRcsUceCapability: " + capability);
- mRcsFeatureConnection.changeEnabledCapabilities(request, null);
- } catch (RemoteException e) {
- loge("enableRcsUceCapability: ", e);
- }
}
/**
* Disable all of the UCE capabilities.
*/
- private void disableAllRcsUceCapabilities() {
+ private void disableAllRcsUceCapabilities() throws android.telephony.ims.ImsException {
final int techLte = ImsRegistrationImplBase.REGISTRATION_TECH_LTE;
final int techIWlan = ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN;
CapabilityChangeRequest request = new CapabilityChangeRequest();
@@ -467,11 +442,17 @@ public class RcsFeatureManager implements IFeatureConnector {
request.addCapabilitiesToDisableForTech(CAPABILITY_OPTIONS, techIWlan);
request.addCapabilitiesToDisableForTech(CAPABILITY_PRESENCE, techLte);
request.addCapabilitiesToDisableForTech(CAPABILITY_PRESENCE, techIWlan);
+ sendCapabilityChangeRequest(request);
+ }
+
+ private void sendCapabilityChangeRequest(CapabilityChangeRequest request)
+ throws android.telephony.ims.ImsException {
try {
- if (DBG) log("disableAllRcsUceCapabilities");
+ if (DBG) log("sendCapabilityChangeRequest: " + request);
mRcsFeatureConnection.changeEnabledCapabilities(request, null);
} catch (RemoteException e) {
- Log.e(TAG, "disableAllRcsUceCapabilities " + e);
+ throw new android.telephony.ims.ImsException("Can not connect to service",
+ android.telephony.ims.ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
}
}
@@ -483,21 +464,6 @@ public class RcsFeatureManager implements IFeatureConnector {
return isCapabilityTypeSupported(mContext, mSlotId, CAPABILITY_PRESENCE);
}
- /**
- * Check if RCS UCE feature is supported by carrier.
- */
- public static boolean isRcsUceSupportedByCarrier(Context context, int slotId) {
- boolean isOptionsSupported = isCapabilityTypeSupported(
- context, slotId, CAPABILITY_OPTIONS);
- boolean isPresenceSupported = isCapabilityTypeSupported(
- context, slotId, CAPABILITY_PRESENCE);
-
- if (DBG) Log.d(TAG, "isRcsUceSupportedByCarrier: options=" + isOptionsSupported
- + ", presence=" + isPresenceSupported);
-
- return isOptionsSupported | isPresenceSupported;
- }
-
/*
* Check if the given type of capability is supported.
*/