Merge "[RCS] Register receiver to listen to the publish state changed and pass the latest result to PersistentService" am: 5304cc7318

Change-Id: I447af7da74f19b25e43ec2feddbbc246fc98178d
diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/CapabilityPolling.java b/rcs/presencepolling/src/com/android/service/ims/presence/CapabilityPolling.java
index d2e2178..87b0dd0 100644
--- a/rcs/presencepolling/src/com/android/service/ims/presence/CapabilityPolling.java
+++ b/rcs/presencepolling/src/com/android/service/ims/presence/CapabilityPolling.java
@@ -31,6 +31,7 @@
 import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -44,7 +45,9 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.ims.ImsException;
+import android.telephony.ims.ImsManager;
 import android.telephony.ims.ProvisioningManager;
+import android.telephony.ims.RcsUceAdapter;
 import android.text.format.TimeMigrationUtils;
 import android.text.TextUtils;
 
@@ -126,6 +129,29 @@
         }
     };
 
+    private RcsUceAdapter.PublishStateCallback mPublishStateCallback =
+            new RcsUceAdapter.PublishStateCallback() {
+        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";
+
+        @Override
+        public void onChanged(int publishState) {
+            logger.info("publish state changed: " + publishState);
+            Intent intent = new Intent(RcsPresence.ACTION_PUBLISH_STATE_CHANGED);
+            intent.putExtra(RcsPresence.EXTRA_PUBLISH_STATE, publishState);
+            mContext.sendStickyBroadcast(intent);
+            launchPersistService(intent);
+        }
+
+        private void launchPersistService(Intent intent) {
+            ComponentName component = new ComponentName(PERSIST_SERVICE_PACKAGE,
+                    PERSIST_SERVICE_NAME);
+            intent.setComponent(component);
+            mContext.startService(intent);
+        }
+    };
+
     private Runnable mRegisterCallbackRunnable = this::tryProvisioningManagerRegistration;
 
     private static CapabilityPolling sInstance = null;
@@ -234,6 +260,7 @@
         cancelDiscoveryAlarm();
         clearPollingTasks();
         mContext.unregisterReceiver(mReceiver);
+        unregisterPublishStateChangedCallback();
         mDiscoveryThread.quit();
 
         if (SubscriptionManager.isValidSubscriptionId(mDefaultSubId)) {
@@ -253,6 +280,29 @@
         mContext.registerReceiver(mReceiver, intentFilter);
     }
 
+    private void registerPublishStateChangedCallback() {
+        try {
+            ImsManager imsManager =
+                    (ImsManager) mContext.getSystemService(Context.TELEPHONY_IMS_SERVICE);
+            RcsUceAdapter uceAdapter = imsManager.getImsRcsManager(mDefaultSubId).getUceAdapter();
+            uceAdapter.registerPublishStateCallback(mContext.getMainExecutor(),
+                    mPublishStateCallback);
+        } catch (Exception ex) {
+            logger.warn("register publish state callback failed, exception: " + ex);
+        }
+    }
+
+    private void unregisterPublishStateChangedCallback() {
+        try {
+            ImsManager imsManager =
+                    (ImsManager) mContext.getSystemService(Context.TELEPHONY_IMS_SERVICE);
+            RcsUceAdapter uceAdapter = imsManager.getImsRcsManager(mDefaultSubId).getUceAdapter();
+            uceAdapter.unregisterPublishStateCallback(mPublishStateCallback);
+        } catch (Exception ex) {
+            logger.warn("unregister publish state callback failed, exception: " + ex);
+        }
+    }
+
     private boolean isPollingReady() {
         RcsManager rcsManager = RcsManager.getInstance(mContext, 0);
         if (rcsManager != null) {
@@ -767,6 +817,8 @@
         if (SubscriptionManager.isValidSubscriptionId(mDefaultSubId)) {
             ProvisioningManager pm = ProvisioningManager.createForSubscriptionId(mDefaultSubId);
             pm.unregisterProvisioningChangedCallback(mProvisioningManagerCallback);
+
+            unregisterPublishStateChangedCallback();
         }
         // register new default and clear old cached values in EAB only if we are changing the
         // default sub ID.
@@ -783,6 +835,7 @@
         enqueueSettingsChanged();
         // load settings for new default.
         enqueueProvisionStateChanged();
+        registerPublishStateChangedCallback();
     }
 
     public void tryProvisioningManagerRegistration() {
diff --git a/rcs/rcsmanager/src/java/com/android/ims/ResultCode.java b/rcs/rcsmanager/src/java/com/android/ims/ResultCode.java
index 2119d5c..8934115 100644
--- a/rcs/rcsmanager/src/java/com/android/ims/ResultCode.java
+++ b/rcs/rcsmanager/src/java/com/android/ims/ResultCode.java
@@ -178,4 +178,18 @@
      * The Client should not send any EAB traffic after get this error.
      */
     public static final int PUBLISH_NOT_PROVISIONED = ResultCode.SUBSCRIBER_ERROR_CODE_END - 3;
+
+    public static final int PUBLISH_NOT_REGISTERED = ResultCode.SUBSCRIBER_ERROR_CODE_END - 4;
+
+    public static final int PUBLISH_FORBIDDEN = ResultCode.SUBSCRIBER_ERROR_CODE_END - 5;
+
+    public static final int PUBLISH_NOT_FOUND = ResultCode.SUBSCRIBER_ERROR_CODE_END - 6;
+
+    public static final int PUBLISH_REQUEST_TIMEOUT = ResultCode.SUBSCRIBER_ERROR_CODE_END - 7;
+
+    public static final int PUBLISH_TOO_LARGE = ResultCode.SUBSCRIBER_ERROR_CODE_END - 8;
+
+    public static final int PUBLISH_TOO_SHORT = ResultCode.SUBSCRIBER_ERROR_CODE_END - 9;
+
+    public static final int PUBLISH_TEMPORARY_ERROR = ResultCode.SUBSCRIBER_ERROR_CODE_END - 10;
 }