From 0a5a8fe7f47dcb749e4cd289bbb0530dfb96471c Mon Sep 17 00:00:00 2001 From: Brad Ebinger Date: Thu, 27 Feb 2020 19:11:59 -0800 Subject: [PATCH] Add new capability polling opt-in intent Adds a new capability discovery opt-in intent, which an application can use to prompt the user to enable contact discovery. Bug: 111305845 Test: atest CtsTelephonyTestCases; telecom test app Change-Id: I42b9d7226a1296bc7e4e86a5ff6448bc8f23d3c0 --- api/current.txt | 14 +++++++ api/system-current.txt | 6 --- api/test-current.txt | 6 --- core/java/android/provider/Telephony.java | 4 +- .../java/android/telephony/ImsManager.java | 3 -- .../android/telephony/ims/ImsException.java | 9 +++-- .../android/telephony/ims/ImsRcsManager.java | 38 ++++++++++++++----- .../android/telephony/ims/RcsUceAdapter.java | 27 +++++++++---- .../telephony/ims/aidl/IImsRcsController.aidl | 5 ++- 9 files changed, 71 insertions(+), 41 deletions(-) diff --git a/api/current.txt b/api/current.txt index a2f2c060428d8..35ac4cb52a301 100644 --- a/api/current.txt +++ b/api/current.txt @@ -48742,6 +48742,7 @@ package android.telephony.ims { public class ImsManager { method @NonNull public android.telephony.ims.ImsMmTelManager getImsMmTelManager(int); + method @NonNull public android.telephony.ims.ImsRcsManager getImsRcsManager(int); field public static final String ACTION_WFC_IMS_REGISTRATION_ERROR = "android.telephony.ims.action.WFC_IMS_REGISTRATION_ERROR"; field public static final String EXTRA_WFC_REGISTRATION_FAILURE_MESSAGE = "android.telephony.ims.extra.WFC_REGISTRATION_FAILURE_MESSAGE"; field public static final String EXTRA_WFC_REGISTRATION_FAILURE_TITLE = "android.telephony.ims.extra.WFC_REGISTRATION_FAILURE_TITLE"; @@ -48770,6 +48771,15 @@ package android.telephony.ims { method public void onCapabilitiesStatusChanged(@NonNull android.telephony.ims.feature.MmTelFeature.MmTelCapabilities); } + public class ImsRcsManager implements android.telephony.ims.RegistrationManager { + method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer); + method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationTransportType(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer); + method @NonNull public android.telephony.ims.RcsUceAdapter getUceAdapter(); + method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RegistrationManager.RegistrationCallback) throws android.telephony.ims.ImsException; + method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.RegistrationManager.RegistrationCallback); + field public static final String ACTION_SHOW_CAPABILITY_DISCOVERY_OPT_IN = "android.telephony.ims.action.SHOW_CAPABILITY_DISCOVERY_OPT_IN"; + } + public final class ImsReasonInfo implements android.os.Parcelable { ctor public ImsReasonInfo(int, int, @Nullable String); method public int describeContents(); @@ -48953,6 +48963,10 @@ package android.telephony.ims { field public static final int EXTRA_CODE_CALL_RETRY_SILENT_REDIAL = 2; // 0x2 } + public class RcsUceAdapter { + method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isUceSettingEnabled() throws android.telephony.ims.ImsException; + } + public interface RegistrationManager { method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer); method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationTransportType(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer); diff --git a/api/system-current.txt b/api/system-current.txt index 3b95f32263411..e01e7549c232f 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -12542,7 +12542,6 @@ package android.telephony.ims { } public class ImsManager { - method @NonNull public android.telephony.ims.ImsRcsManager getImsRcsManager(int); field public static final String ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION = "com.android.internal.intent.action.ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION"; } @@ -12570,10 +12569,6 @@ package android.telephony.ims { ctor @Deprecated public ImsMmTelManager.RegistrationCallback(); } - public class ImsRcsManager implements android.telephony.ims.RegistrationManager { - method @NonNull public android.telephony.ims.RcsUceAdapter getUceAdapter(); - } - public final class ImsReasonInfo implements android.os.Parcelable { field public static final String EXTRA_MSG_SERVICE_NOT_AUTHORIZED = "Forbidden. Not Authorized for Service"; } @@ -12950,7 +12945,6 @@ package android.telephony.ims { } public class RcsUceAdapter { - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isUceSettingEnabled() throws android.telephony.ims.ImsException; method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUceSettingEnabled(boolean) throws android.telephony.ims.ImsException; } diff --git a/api/test-current.txt b/api/test-current.txt index 0f8694f7435bb..aff0f04ee0de8 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -4040,7 +4040,6 @@ package android.telephony.ims { } public class ImsManager { - method @NonNull public android.telephony.ims.ImsRcsManager getImsRcsManager(int); field public static final String ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION = "com.android.internal.intent.action.ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION"; } @@ -4068,10 +4067,6 @@ package android.telephony.ims { ctor @Deprecated public ImsMmTelManager.RegistrationCallback(); } - public class ImsRcsManager implements android.telephony.ims.RegistrationManager { - method @NonNull public android.telephony.ims.RcsUceAdapter getUceAdapter(); - } - public class ImsService extends android.app.Service { ctor public ImsService(); method public android.telephony.ims.feature.MmTelFeature createMmTelFeature(int); @@ -4444,7 +4439,6 @@ package android.telephony.ims { } public class RcsUceAdapter { - method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public boolean isUceSettingEnabled() throws android.telephony.ims.ImsException; method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUceSettingEnabled(boolean) throws android.telephony.ims.ImsException; } diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java index adfa885f121e0..97f7533c32099 100644 --- a/core/java/android/provider/Telephony.java +++ b/core/java/android/provider/Telephony.java @@ -5120,8 +5120,8 @@ public final class Telephony { public static final String WFC_IMS_ROAMING_ENABLED = "wfc_ims_roaming_enabled"; /** - * Determines if the user has enabled IMS RCS User Capability Exchange (UCE) for this - * subscription. + * TelephonyProvider column name for determining if the user has enabled IMS RCS User + * Capability Exchange (UCE) for this subscription. */ public static final String IMS_RCS_UCE_ENABLED = "ims_rcs_uce_enabled"; diff --git a/telephony/java/android/telephony/ImsManager.java b/telephony/java/android/telephony/ImsManager.java index 704e5aa781888..d504b381d1a13 100644 --- a/telephony/java/android/telephony/ImsManager.java +++ b/telephony/java/android/telephony/ImsManager.java @@ -103,10 +103,7 @@ public class ImsManager { * @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. - * @hide */ - @SystemApi - @TestApi @NonNull public ImsRcsManager getImsRcsManager(int subscriptionId) { if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) { diff --git a/telephony/java/android/telephony/ims/ImsException.java b/telephony/java/android/telephony/ims/ImsException.java index 643f452d2e757..1c3d58d98b4a5 100644 --- a/telephony/java/android/telephony/ims/ImsException.java +++ b/telephony/java/android/telephony/ims/ImsException.java @@ -47,11 +47,12 @@ public final class ImsException extends Exception { public static final int CODE_ERROR_SERVICE_UNAVAILABLE = 1; /** - * This device or carrier configuration does not support IMS for this subscription. + * This device or carrier configuration does not support this feature for this subscription. *

- * This is a permanent configuration error and there should be no retry. Usually this is - * because {@link PackageManager#FEATURE_TELEPHONY_IMS} is not available - * or the device has no ImsService implementation to service this request. + * This is a permanent configuration error and there should be no retry until the subscription + * changes if this operation is denied due to a carrier configuration. If this is due to a + * device configuration, the feature {@link PackageManager#FEATURE_TELEPHONY_IMS} is not + * available or the device has no ImsService implementation to service this request. */ public static final int CODE_ERROR_UNSUPPORTED_OPERATION = 2; diff --git a/telephony/java/android/telephony/ims/ImsRcsManager.java b/telephony/java/android/telephony/ims/ImsRcsManager.java index c506cd5879d8c..151fb59b7550c 100644 --- a/telephony/java/android/telephony/ims/ImsRcsManager.java +++ b/telephony/java/android/telephony/ims/ImsRcsManager.java @@ -20,13 +20,15 @@ import android.Manifest; import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.annotation.RequiresPermission; -import android.annotation.SystemApi; -import android.annotation.TestApi; +import android.annotation.SdkConstant; import android.content.Context; +import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; +import android.provider.Settings; import android.telephony.AccessNetworkConstants; +import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyFrameworkInitializer; import android.telephony.ims.aidl.IImsCapabilityCallback; @@ -46,13 +48,33 @@ import java.util.function.Consumer; * (UCE) service, as well as managing user settings. * * Use {@link ImsManager#getImsRcsManager(int)} to create an instance of this manager. - * @hide */ -@SystemApi -@TestApi public class ImsRcsManager implements RegistrationManager { private static final String TAG = "ImsRcsManager"; + /** + * Activity Action: Show the opt-in dialog for enabling or disabling RCS contact discovery + * using User Capability Exchange (UCE). + *

+ * An application that depends on contact discovery being enabled may send this intent + * using {@link Context#startActivity(Intent)} to ask the user to opt-in for contacts upload for + * capability exchange if it is currently disabled. Whether or not this setting has been enabled + * can be queried using {@link RcsUceAdapter#isUceSettingEnabled()}. + *

+ * This intent should only be sent if the carrier supports RCS capability exchange, which can be + * queried using the key {@link CarrierConfigManager#KEY_USE_RCS_PRESENCE_BOOL}. Otherwise, the + * setting will not be present. + *

+ * Input: A mandatory {@link Settings#EXTRA_SUB_ID} extra containing the subscription that the + * setting will be be shown for. + *

+ * Output: Nothing + * @see RcsUceAdapter + */ + @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_SHOW_CAPABILITY_DISCOVERY_OPT_IN = + "android.telephony.ims.action.SHOW_CAPABILITY_DISCOVERY_OPT_IN"; + /** * Receives RCS availability status updates from the ImsService. * @@ -145,11 +167,10 @@ public class ImsRcsManager implements RegistrationManager { */ @NonNull public RcsUceAdapter getUceAdapter() { - return new RcsUceAdapter(mSubId); + return new RcsUceAdapter(mContext, mSubId); } /** - * {@inheritDoc} * @hide */ @Override @@ -181,7 +202,6 @@ public class ImsRcsManager implements RegistrationManager { } /** - * {@inheritDoc * @hide */ @Override @@ -206,7 +226,6 @@ public class ImsRcsManager implements RegistrationManager { } /** - * {@inheritDoc} * @hide */ @Override @@ -239,7 +258,6 @@ public class ImsRcsManager implements RegistrationManager { } /** - * {@inheritDoc} * @hide */ @Override diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java index fc7c1ee994309..58e9b70080500 100644 --- a/telephony/java/android/telephony/ims/RcsUceAdapter.java +++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java @@ -23,10 +23,13 @@ import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.TestApi; +import android.content.Context; +import android.database.ContentObserver; import android.net.Uri; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; +import android.provider.Telephony; import android.telephony.TelephonyFrameworkInitializer; import android.telephony.ims.aidl.IImsRcsController; import android.telephony.ims.aidl.IRcsUceControllerCallback; @@ -42,10 +45,7 @@ import java.util.concurrent.Executor; * Manages RCS User Capability Exchange for the subscription specified. * * @see ImsRcsManager#getUceAdapter() for information on creating an instance of this class. - * @hide */ -@SystemApi -@TestApi public class RcsUceAdapter { private static final String TAG = "RcsUceAdapter"; @@ -215,6 +215,7 @@ public class RcsUceAdapter { } } + private final Context mContext; private final int mSubId; /** @@ -222,7 +223,8 @@ public class RcsUceAdapter { * {@link ImsRcsManager#getUceAdapter()} to instantiate this manager class. * @hide */ - RcsUceAdapter(int subId) { + RcsUceAdapter(Context context, int subId) { + mContext = context; mSubId = subId; } @@ -290,7 +292,8 @@ public class RcsUceAdapter { }; try { - imsRcsController.requestCapabilities(mSubId, contactNumbers, internalCallback); + imsRcsController.requestCapabilities(mSubId, mContext.getOpPackageName(), + mContext.getFeatureId(), contactNumbers, internalCallback); } catch (RemoteException e) { Log.e(TAG, "Error calling IImsRcsController#requestCapabilities", e); throw new ImsException("Remote IMS Service is not available", @@ -340,7 +343,7 @@ public class RcsUceAdapter { * available. This can happen if the ImsService has crashed, for example, or if the subscription * becomes inactive. See {@link ImsException#getCode()} for more information on the error codes. */ - @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + @RequiresPermission(Manifest.permission.READ_PHONE_STATE) public boolean isUceSettingEnabled() throws ImsException { IImsRcsController imsRcsController = getIImsRcsController(); if (imsRcsController == null) { @@ -348,9 +351,10 @@ public class RcsUceAdapter { throw new ImsException("Can not find remote IMS service", ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); } - try { - return imsRcsController.isUceSettingEnabled(mSubId); + // Telephony.SimInfo#IMS_RCS_UCE_ENABLED can also be used to listen to changes to this. + return imsRcsController.isUceSettingEnabled(mSubId, mContext.getOpPackageName(), + mContext.getFeatureId()); } catch (RemoteException e) { Log.e(TAG, "Error calling IImsRcsController#isUceSettingEnabled", e); throw new ImsException("Remote IMS Service is not available", @@ -361,6 +365,10 @@ public class RcsUceAdapter { /** * Change the user’s setting for whether or not UCE is enabled for the associated subscription. *

+ * If an application Requires UCE, they may launch an Activity using the Intent + * {@link ImsRcsManager#ACTION_SHOW_CAPABILITY_DISCOVERY_OPT_IN}, which will ask the user if + * they wish to enable this feature. + *

* Note: This setting does not affect whether or not the device publishes its service * capabilities if the subscription supports presence publication. * @@ -370,7 +378,10 @@ public class RcsUceAdapter { * {@link RcsUceAdapter} is valid, but the ImsService associated with the subscription is not * available. This can happen if the ImsService has crashed, for example, or if the subscription * becomes inactive. See {@link ImsException#getCode()} for more information on the error codes. + * @hide */ + @SystemApi + @TestApi @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) public void setUceSettingEnabled(boolean isEnabled) throws ImsException { IImsRcsController imsRcsController = getIImsRcsController(); diff --git a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl index 6f6aa44371fae..483c66eedc0ce 100644 --- a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl @@ -42,8 +42,9 @@ interface IImsRcsController { boolean isAvailable(int subId, int capability); // ImsUceAdapter specific - void requestCapabilities(int subId, in List contactNumbers, IRcsUceControllerCallback c); + void requestCapabilities(int subId, String callingPackage, String callingFeatureId, + in List contactNumbers, IRcsUceControllerCallback c); int getUcePublishState(int subId); - boolean isUceSettingEnabled(int subId); + boolean isUceSettingEnabled(int subId, String callingPackage, String callingFeatureId); void setUceSettingEnabled(int subId, boolean isEnabled); }