Turn off polling until user opt-in occurs

Deny contact capability requests until opt-in
occurs.

Bug: 111305845
Test: atest CtsTelephonyTestCases;manual
Merged-In: I3acf2c5b16239e97cd445d5f9cd04002c0d94707
Change-Id: I3acf2c5b16239e97cd445d5f9cd04002c0d94707
diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/PollingService.java b/rcs/presencepolling/src/com/android/service/ims/presence/PollingService.java
index b41baa7..ed511e7 100644
--- a/rcs/presencepolling/src/com/android/service/ims/presence/PollingService.java
+++ b/rcs/presencepolling/src/com/android/service/ims/presence/PollingService.java
@@ -33,12 +33,18 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.provider.Telephony;
 import android.telephony.CarrierConfigManager;
 import android.os.IBinder;
 import android.os.PersistableBundle;
 import android.os.ServiceManager;
 import android.os.SystemProperties;
 import android.telephony.SubscriptionManager;
+import android.telephony.ims.ImsManager;
+import android.telephony.ims.ImsRcsManager;
+import android.util.Log;
 
 import com.android.ims.internal.Logger;
 import com.android.internal.annotations.VisibleForTesting;
@@ -49,6 +55,9 @@
  */
 public class PollingService extends Service {
 
+    private static final Uri UCE_URI = Uri.withAppendedPath(Telephony.SimInfo.CONTENT_URI,
+            Telephony.SimInfo.COLUMN_IMS_RCS_UCE_ENABLED);
+
     private Logger logger = Logger.getLogger(this.getClass().getName());
 
     private CapabilityPolling mCapabilityPolling = null;
@@ -71,6 +80,8 @@
         }
     };
 
+    private ContentObserver mUceSettingObserver;
+
     private SubscriptionManager.OnSubscriptionsChangedListener mSubChangedListener =
             new SubscriptionManager.OnSubscriptionsChangedListener() {
                 @Override
@@ -97,6 +108,20 @@
         // start polling.
         subscriptionManager.addOnSubscriptionsChangedListener(getMainExecutor(),
                 mSubChangedListener);
+        mUceSettingObserver = new ContentObserver(getMainThreadHandler()) {
+            @Override
+            public void onChange(boolean selfChange) {
+                onChange(selfChange, null /*uri*/);
+            }
+
+            @Override
+            public void onChange(boolean selfChange, Uri uri) {
+                logger.print("UCE setting changed, re-evaluating poll service.");
+                checkAndUpdateCapabilityPollStatus();
+            }
+        };
+        getContentResolver().registerContentObserver(UCE_URI, true /*notifyForDescendants*/,
+                mUceSettingObserver);
     }
 
     /**
@@ -113,6 +138,9 @@
         SubscriptionManager subscriptionManager = getSystemService(SubscriptionManager.class);
         subscriptionManager.removeOnSubscriptionsChangedListener(mSubChangedListener);
         unregisterReceiver(mReceiver);
+        if (mUceSettingObserver != null) {
+            getContentResolver().unregisterContentObserver(mUceSettingObserver);
+        }
 
         super.onDestroy();
     }
@@ -164,8 +192,12 @@
 
     private void checkAndUpdateCapabilityPollStatus() {
         // If the carrier doesn't support RCS Presence, stop polling.
-        if (!isRcsSupportedByCarrier()) {
-            logger.info("RCS not supported by carrier. Stopping CapabilityPolling");
+        boolean carrierSupport = isRcsSupportedByCarrier();
+        boolean userEnabled = hasUserEnabledUce();
+        logger.print("RCS carrier support = " + carrierSupport + ", user enabled = "
+                + userEnabled);
+        if (!carrierSupport || !userEnabled) {
+            logger.print("RCS UCE Not supported, Stopping CapabilityPolling");
             if (mCapabilityPolling != null) {
                 mCapabilityPolling.stop();
                 mCapabilityPolling = null;
@@ -180,6 +212,21 @@
         }
     }
 
+    private boolean hasUserEnabledUce() {
+        ImsManager manager = getSystemService(ImsManager.class);
+        if (manager == null) {
+            logger.error("hasUserEnabledUce: manager not available.");
+            return false;
+        }
+        try {
+            ImsRcsManager rcsManager = manager.getImsRcsManager(mDefaultSubId);
+            return (rcsManager != null) && rcsManager.getUceAdapter().isUceSettingEnabled();
+        } catch (Exception e) {
+            logger.error("hasUserEnabledUce: exception = " + e.getMessage());
+        }
+        return false;
+    }
+
     private boolean isRcsSupportedByCarrier() {
         CarrierConfigManager configManager = getSystemService(CarrierConfigManager.class);
         if (configManager != null) {
diff --git a/rcs/rcsservice/src/com/android/service/ims/RcsSettingUtils.java b/rcs/rcsservice/src/com/android/service/ims/RcsSettingUtils.java
index 9ef176e..13e0f42 100644
--- a/rcs/rcsservice/src/com/android/service/ims/RcsSettingUtils.java
+++ b/rcs/rcsservice/src/com/android/service/ims/RcsSettingUtils.java
@@ -35,7 +35,9 @@
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.ims.ImsException;
+import android.telephony.ims.ImsManager;
 import android.telephony.ims.ImsMmTelManager;
+import android.telephony.ims.ImsRcsManager;
 import android.telephony.ims.ProvisioningManager;
 import android.telephony.ims.feature.MmTelFeature;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
@@ -132,6 +134,21 @@
         return isProvisioned;
     }
 
+    public static boolean hasUserEnabledContactDiscovery(Context context, int subId) {
+        if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            logger.debug("hasUserEnabledContactDiscovery: no valid subscriptions!");
+            return false;
+        }
+        try {
+            ImsManager imsManager = context.getSystemService(ImsManager.class);
+            ImsRcsManager rcsManager = imsManager.getImsRcsManager(subId);
+            return rcsManager.getUceAdapter().isUceSettingEnabled();
+        } catch (Exception e) {
+            logger.warn("hasUserEnabledContactDiscovery: Exception = " + e.getMessage());
+            return false;
+        }
+    }
+
     public static int getSIPT1Timer(int subId) {
         int sipT1Timer = 0;
         try {
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 2071567..c804675 100644
--- a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceSubscriber.java
+++ b/rcs/rcsservice/src/com/android/service/ims/presence/PresenceSubscriber.java
@@ -132,6 +132,12 @@
             return ResultCode.SUBSCRIBE_NOT_REGISTERED;
         }
 
+        if (!RcsSettingUtils.hasUserEnabledContactDiscovery(mContext, mAssociatedSubscription)) {
+            logger.warn("requestCapability request has been denied due to contact discovery being "
+                    + "disabled by the user");
+            return ResultCode.ERROR_SERVICE_NOT_ENABLED;
+        }
+
         int ret = subscriber.getStackStatusForCapabilityRequest();
         if (ret < ResultCode.SUCCESS) {
             logger.error("requestCapability ret=" + ret);
@@ -197,6 +203,12 @@
             return ret;
         }
 
+        if (!RcsSettingUtils.hasUserEnabledContactDiscovery(mContext, mAssociatedSubscription)) {
+            logger.warn("requestCapability request has been denied due to contact discovery being "
+                    + "disabled by the user");
+            return ResultCode.ERROR_SERVICE_NOT_ENABLED;
+        }
+
         if(!forceToNetwork){
             logger.debug("check if we can use the value in cache");
             int availabilityExpire =