Merge "[RCS] Create AIDL layer for RcsUceAdapter, create RCS UCE controller implementation in Telephony."
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 77647c5..646f0dc 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -173,6 +173,7 @@
import android.telephony.TelephonyManager;
import android.telephony.euicc.EuiccCardManager;
import android.telephony.euicc.EuiccManager;
+import android.telephony.ims.ImsManager;
import android.telephony.ims.RcsMessageManager;
import android.util.ArrayMap;
import android.util.Log;
@@ -630,6 +631,14 @@
}
});
+ registerService(Context.TELEPHONY_IMS_SERVICE, ImsManager.class,
+ new CachedServiceFetcher<ImsManager>() {
+ @Override
+ public ImsManager createService(ContextImpl ctx) {
+ return new ImsManager(ctx.getOuterContext());
+ }
+ });
+
registerService(Context.CARRIER_CONFIG_SERVICE, CarrierConfigManager.class,
new CachedServiceFetcher<CarrierConfigManager>() {
@Override
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index cd6acba..a8c1216 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4726,6 +4726,13 @@
/**
* Use with {@link #getSystemService(String)} to retrieve an
+ * {@link android.telephony.ims.ImsManager}.
+ * @hide
+ */
+ public static final String TELEPHONY_IMS_SERVICE = "telephony_ims";
+
+ /**
+ * Use with {@link #getSystemService(String)} to retrieve an
* {@link android.telephony.ims.RcsMessageManager}.
* @hide
*/
diff --git a/telephony/java/android/telephony/ImsManager.java b/telephony/java/android/telephony/ImsManager.java
new file mode 100644
index 0000000..02d8be3
--- /dev/null
+++ b/telephony/java/android/telephony/ImsManager.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import android.annotation.SystemService;
+import android.content.Context;
+import android.telephony.SubscriptionManager;
+
+/**
+ * Provides access to information about Telephony IMS services on the device.
+ *
+ * @hide
+ */
+@SystemService(Context.TELEPHONY_IMS_SERVICE)
+public class ImsManager {
+
+ private Context mContext;
+
+ public ImsManager(Context context) {
+ mContext = context;
+ }
+
+ /**
+ * Create an instance of ImsRcsManager for the subscription id specified.
+ *
+ * @param subscriptionId The ID of the subscription that this ImsRcsManager will use.
+ * @throws IllegalArgumentException if the subscription is invalid.
+ * @return a ImsRcsManager instance with the specific subscription ID.
+ */
+ public ImsRcsManager getImsRcsManager(int subscriptionId) {
+ if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) {
+ throw new IllegalArgumentException("Invalid subscription ID: " + subscriptionId);
+ }
+
+ return new ImsRcsManager(mContext, subscriptionId);
+ }
+
+ /**
+ * Create an instance of ImsMmTelManager for the subscription id specified.
+ *
+ * @param subscriptionId The ID of the subscription that this ImsMmTelManager will use.
+ * @throws IllegalArgumentException if the subscription is invalid.
+ * @return a ImsMmTelManager instance with the specific subscription ID.
+ */
+ public ImsMmTelManager getImsMmTelManager(int subscriptionId) {
+ if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) {
+ throw new IllegalArgumentException("Invalid subscription ID: " + subscriptionId);
+ }
+
+ return new ImsMmTelManager(subscriptionId);
+ }
+}
diff --git a/telephony/java/android/telephony/ims/ImsRcsManager.java b/telephony/java/android/telephony/ims/ImsRcsManager.java
index 6432016..21707b0 100644
--- a/telephony/java/android/telephony/ims/ImsRcsManager.java
+++ b/telephony/java/android/telephony/ims/ImsRcsManager.java
@@ -22,11 +22,15 @@
import android.annotation.RequiresPermission;
import android.content.Context;
import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
import android.telephony.AccessNetworkConstants;
-import android.telephony.SubscriptionManager;
import android.telephony.ims.aidl.IImsCapabilityCallback;
+import android.telephony.ims.aidl.IImsRcsController;
import android.telephony.ims.feature.ImsFeature;
import android.telephony.ims.feature.RcsFeature;
+import android.util.Log;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
@@ -35,10 +39,11 @@
* Manager for interfacing with the framework RCS services, including the User Capability Exchange
* (UCE) service, as well as managing user settings.
*
- * Use {@link #createForSubscriptionId(Context, int)} to create an instance of this manager.
+ * Use {@link ImsManager#getImsRcsManager(int)} to create an instance of this manager.
* @hide
*/
public class ImsRcsManager implements RegistrationManager {
+ private static final String TAG = "ImsRcsManager";
/**
* Receives RCS availability status updates from the ImsService.
@@ -112,30 +117,23 @@
private final int mSubId;
private final Context mContext;
-
/**
- * Create an instance of ImsRcsManager for the subscription id specified.
- *
- * @param context The context to create this ImsRcsManager instance within.
- * @param subscriptionId The ID of the subscription that this ImsRcsManager will use.
- * @see android.telephony.SubscriptionManager#getActiveSubscriptionInfoList()
- * @throws IllegalArgumentException if the subscription is invalid.
+ * Use {@link ImsManager#getImsRcsManager(int)} to create an instance of this class.
* @hide
*/
- public static ImsRcsManager createForSubscriptionId(Context context, int subscriptionId) {
- if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) {
- throw new IllegalArgumentException("Invalid subscription ID");
- }
-
- return new ImsRcsManager(context, subscriptionId);
+ public ImsRcsManager(Context context, int subId) {
+ mSubId = subId;
+ mContext = context;
}
/**
- * Use {@link #createForSubscriptionId(Context, int)} to create an instance of this class.
+ * @return A {@link RcsUceAdapter} used for User Capability Exchange (UCE) operations for
+ * this subscription.
+ * @hide
*/
- private ImsRcsManager(Context context, int subId) {
- mContext = context;
- mSubId = subId;
+ @NonNull
+ public RcsUceAdapter getUceAdapter() {
+ return new RcsUceAdapter(mSubId);
}
/**{@inheritDoc}*/
@@ -225,9 +223,22 @@
if (executor == null) {
throw new IllegalArgumentException("Must include a non-null Executor.");
}
+
+ IImsRcsController imsRcsController = getIImsRcsController();
+ if (imsRcsController == null) {
+ Log.e(TAG, "Register availability callback: IImsRcsController is null");
+ throw new ImsException("Can not find remote IMS service",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
+
c.setExecutor(executor);
- throw new UnsupportedOperationException("registerRcsAvailabilityCallback is not"
- + "supported.");
+ try {
+ imsRcsController.registerRcsAvailabilityCallback(c.getBinder());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling IImsRcsController#registerRcsAvailabilityCallback", e);
+ throw new ImsException("Remote IMS Service is not available",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
}
/**
@@ -238,14 +249,31 @@
* inactive subscription, it will result in a no-op.
* @param c The RCS {@link AvailabilityCallback} to be removed.
* @see #registerRcsAvailabilityCallback(Executor, AvailabilityCallback)
+ * @throws ImsException if the IMS service is not available when calling this method
+ * {@link ImsRcsController#unregisterRcsAvailabilityCallback()}.
+ * See {@link ImsException#getCode()} for more information on the error codes.
*/
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
- public void unregisterRcsAvailabilityCallback(@NonNull AvailabilityCallback c) {
+ public void unregisterRcsAvailabilityCallback(@NonNull AvailabilityCallback c)
+ throws ImsException {
if (c == null) {
throw new IllegalArgumentException("Must include a non-null AvailabilityCallback.");
}
- throw new UnsupportedOperationException("unregisterRcsAvailabilityCallback is not"
- + "supported.");
+
+ IImsRcsController imsRcsController = getIImsRcsController();
+ if (imsRcsController == null) {
+ Log.e(TAG, "Unregister availability callback: IImsRcsController is null");
+ throw new ImsException("Can not find remote IMS service",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
+
+ try {
+ imsRcsController.unregisterRcsAvailabilityCallback(c.getBinder());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling IImsRcsController#unregisterRcsAvailabilityCallback", e);
+ throw new ImsException("Remote IMS Service is not available",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
}
/**
@@ -260,10 +288,27 @@
* rather the subscription is capable of this service over IMS.
* @see #isAvailable(int)
* @see android.telephony.CarrierConfigManager#KEY_USE_RCS_PRESENCE_BOOL
+ * @throws ImsException if the IMS service is not available when calling this method
+ * {@link ImsRcsController#isCapable(int, int)}.
+ * See {@link ImsException#getCode()} for more information on the error codes.
*/
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
- public boolean isCapable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability) {
- throw new UnsupportedOperationException("isCapable is not supported.");
+ public boolean isCapable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability)
+ throws ImsException {
+ IImsRcsController imsRcsController = getIImsRcsController();
+ if (imsRcsController == null) {
+ Log.e(TAG, "isCapable: IImsRcsController is null");
+ throw new ImsException("Can not find remote IMS service",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
+
+ try {
+ return imsRcsController.isCapable(mSubId, capability);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling IImsRcsController#isCapable", e);
+ throw new ImsException("Remote IMS Service is not available",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
}
/**
@@ -277,18 +322,31 @@
* false otherwise. If the capability is available, IMS is registered and the service is
* currently available over IMS.
* @see #isCapable(int)
+ * @throws ImsException if the IMS service is not available when calling this method
+ * {@link ImsRcsController#isAvailable(int, int)}.
+ * See {@link ImsException#getCode()} for more information on the error codes.
*/
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
- public boolean isAvailable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability) {
- throw new UnsupportedOperationException("isAvailable is not supported.");
+ public boolean isAvailable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability)
+ throws ImsException {
+ IImsRcsController imsRcsController = getIImsRcsController();
+ if (imsRcsController == null) {
+ Log.e(TAG, "isAvailable: IImsRcsController is null");
+ throw new ImsException("Can not find remote IMS service",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
+
+ try {
+ return imsRcsController.isAvailable(mSubId, capability);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling IImsRcsController#isAvailable", e);
+ throw new ImsException("Remote IMS Service is not available",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
}
- /**
- * @return A new {@link RcsUceAdapter} used for User Capability Exchange (UCE) operations for
- * this subscription.
- */
- @NonNull
- public RcsUceAdapter getUceAdapter() {
- return new RcsUceAdapter(mSubId);
+ private IImsRcsController getIImsRcsController() {
+ IBinder binder = ServiceManager.getService(Context.TELEPHONY_IMS_SERVICE);
+ return IImsRcsController.Stub.asInterface(binder);
}
}
diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java
index a6a7a84..b47bcb9 100644
--- a/telephony/java/android/telephony/ims/RcsUceAdapter.java
+++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java
@@ -23,6 +23,13 @@
import android.annotation.RequiresPermission;
import android.content.Context;
import android.net.Uri;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.telephony.ims.aidl.IImsRcsController;
+import android.telephony.ims.aidl.IRcsUceControllerCallback;
+import android.util.Log;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -36,6 +43,7 @@
* @hide
*/
public class RcsUceAdapter {
+ private static final String TAG = "RcsUceAdapter";
/**
* An unknown error has caused the request to fail.
@@ -188,7 +196,6 @@
/**
* Not to be instantiated directly, use
- * {@link ImsRcsManager#createForSubscriptionId(Context, int)} and
* {@link ImsRcsManager#getUceAdapter()} to instantiate this manager class.
*/
RcsUceAdapter(int subId) {
@@ -218,7 +225,45 @@
public void requestCapabilities(@CallbackExecutor Executor executor,
@NonNull List<Uri> contactNumbers,
@NonNull CapabilitiesCallback c) throws ImsException {
- throw new UnsupportedOperationException("isUceSettingEnabled is not supported.");
+ if (c == null) {
+ throw new IllegalArgumentException("Must include a non-null AvailabilityCallback.");
+ }
+ if (executor == null) {
+ throw new IllegalArgumentException("Must include a non-null Executor.");
+ }
+ if (contactNumbers == null) {
+ throw new IllegalArgumentException("Must include non-null contact number list.");
+ }
+
+ IImsRcsController imsRcsController = getIImsRcsController();
+ if (imsRcsController == null) {
+ Log.e(TAG, "requestCapabilities: IImsRcsController is null");
+ throw new ImsException("Can not find remote IMS service",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
+
+ IRcsUceControllerCallback internalCallback = new IRcsUceControllerCallback.Stub() {
+ @Override
+ public void onCapabilitiesReceived(List<RcsContactUceCapability> contactCapabilities) {
+ Binder.withCleanCallingIdentity(() ->
+ executor.execute(() ->
+ c.onCapabilitiesReceived(contactCapabilities)));
+ }
+ @Override
+ public void onError(int errorCode) {
+ Binder.withCleanCallingIdentity(() ->
+ executor.execute(() ->
+ c.onError(errorCode)));
+ }
+ };
+
+ try {
+ imsRcsController.requestCapabilities(mSubId, contactNumbers, internalCallback);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling IImsRcsController#requestCapabilities", e);
+ throw new ImsException("Remote IMS Service is not available",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
}
/**
@@ -233,7 +278,20 @@
*/
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public @PublishState int getUcePublishState() throws ImsException {
- throw new UnsupportedOperationException("getPublishState is not supported.");
+ IImsRcsController imsRcsController = getIImsRcsController();
+ if (imsRcsController == null) {
+ Log.e(TAG, "getUcePublishState: IImsRcsController is null");
+ throw new ImsException("Can not find remote IMS service",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
+
+ try {
+ return imsRcsController.getUcePublishState(mSubId);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling IImsRcsController#getUcePublishState", e);
+ throw new ImsException("Remote IMS Service is not available",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
}
/**
@@ -252,9 +310,22 @@
*/
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public boolean isUceSettingEnabled() throws ImsException {
- // TODO: add SubscriptionController column for this property.
- throw new UnsupportedOperationException("isUceSettingEnabled is not supported.");
+ IImsRcsController imsRcsController = getIImsRcsController();
+ if (imsRcsController == null) {
+ Log.e(TAG, "isUceSettingEnabled: IImsRcsController is null");
+ throw new ImsException("Can not find remote IMS service",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
+
+ try {
+ return imsRcsController.isUceSettingEnabled(mSubId);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling IImsRcsController#isUceSettingEnabled", e);
+ throw new ImsException("Remote IMS Service is not available",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
}
+
/**
* Change the user’s setting for whether or not UCE is enabled for the associated subscription.
* @param isEnabled the user's setting for whether or not they wish for Presence and User
@@ -270,7 +341,24 @@
*/
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public void setUceSettingEnabled(boolean isEnabled) throws ImsException {
- // TODO: add SubscriptionController column for this property.
- throw new UnsupportedOperationException("setUceSettingEnabled is not supported.");
+ IImsRcsController imsRcsController = getIImsRcsController();
+ if (imsRcsController == null) {
+ Log.e(TAG, "setUceSettingEnabled: IImsRcsController is null");
+ throw new ImsException("Can not find remote IMS service",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
+
+ try {
+ imsRcsController.setUceSettingEnabled(mSubId, isEnabled);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling IImsRcsController#setUceSettingEnabled", e);
+ throw new ImsException("Remote IMS Service is not available",
+ ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
+ }
+
+ private IImsRcsController getIImsRcsController() {
+ IBinder binder = ServiceManager.getService(Context.TELEPHONY_IMS_SERVICE);
+ return IImsRcsController.Stub.asInterface(binder);
}
}
diff --git a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
new file mode 100644
index 0000000..b379bd0
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims.aidl;
+
+import android.net.Uri;
+import android.telephony.ims.aidl.IImsCapabilityCallback;
+import android.telephony.ims.aidl.IRcsUceControllerCallback;
+
+/**
+ * Interface used to interact with the Telephony IMS.
+ *
+ * {@hide}
+ */
+interface IImsRcsController {
+ void registerRcsAvailabilityCallback(IImsCapabilityCallback c);
+ void unregisterRcsAvailabilityCallback(IImsCapabilityCallback c);
+ boolean isCapable(int subId, int capability);
+ boolean isAvailable(int subId, int capability);
+
+ // ImsUceAdapter specific
+ void requestCapabilities(int subId, in List<Uri> contactNumbers, IRcsUceControllerCallback c);
+ int getUcePublishState(int subId);
+ boolean isUceSettingEnabled(int subId);
+ void setUceSettingEnabled(int subId, boolean isEnabled);
+}
diff --git a/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl b/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl
new file mode 100644
index 0000000..5975930
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims.aidl;
+
+import android.telephony.ims.RcsContactUceCapability;
+
+/**
+ * Provides interface for RCS UCE when receive a change.
+ *
+ * {@hide}
+ */
+oneway interface IRcsUceControllerCallback {
+ void onCapabilitiesReceived(in List<RcsContactUceCapability> contactCapabilities);
+ void onError(int errorCode);
+}