CFI for individual subscriptions

Based on the subscription select the corresponding CFI from the resource
and display it on the UI.

Test: manual - Display the call forwarding indication at each SIM when
several SIM cards that enabled call forwarding or voicemail message
received are inserted.
Bug: 34871334
Change-Id: Ia9741c70e701cd5953881888751cd5ddf3203563
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index 3f44130..d084e92 100644
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -44,10 +44,15 @@
 import android.util.ArrayMap;
 import android.util.Log;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
+import com.android.internal.telephony.SubscriptionController;
+
 /**
  * Phone app module that listens for phone state changes and various other
  * events from the telephony layer, and triggers any resulting UI behavior
@@ -68,7 +73,8 @@
 
     private Map<Integer, CallNotifierPhoneStateListener> mPhoneStateListeners =
             new ArrayMap<Integer, CallNotifierPhoneStateListener>();
-
+    private Map<Integer, Boolean> mCFIStatus = new ArrayMap<Integer, Boolean>();
+    private Map<Integer, Boolean> mMWIStatus = new ArrayMap<Integer, Boolean>();
     private PhoneGlobals mApplication;
     private CallManager mCM;
     private BluetoothHeadset mBluetoothHeadset;
@@ -140,7 +146,7 @@
                 new OnSubscriptionsChangedListener() {
                     @Override
                     public void onSubscriptionsChanged() {
-                        updatePhoneStateListeners();
+                        updatePhoneStateListeners(true);
                     }
                 });
     }
@@ -571,14 +577,26 @@
                 SHOW_MESSAGE_NOTIFICATION_TIME);
     }
 
-    public void updatePhoneStateListeners() {
+    public void updatePhoneStateListeners(boolean isRefresh) {
         List<SubscriptionInfo> subInfos = mSubscriptionManager.getActiveSubscriptionInfoList();
 
-        // Unregister phone listeners for inactive subscriptions.
-        Iterator<Integer> itr = mPhoneStateListeners.keySet().iterator();
-        while (itr.hasNext()) {
-            int subId = itr.next();
+        // Sort sub id list based on slot id, so that CFI/MWI notifications will be updated for
+        // slot 0 first then slot 1. This is needed to ensure that when CFI or MWI is enabled for
+        // both slots, user always sees icon related to slot 0 on left side followed by that of
+        // slot 1.
+        List<Integer> subIdList = new ArrayList<Integer>(mPhoneStateListeners.keySet());
+        Collections.sort(subIdList, new Comparator<Integer>() {
+            public int compare(Integer sub1, Integer sub2) {
+                int slotId1 = SubscriptionController.getInstance().getSlotIndex(sub1);
+                int slotId2 = SubscriptionController.getInstance().getSlotIndex(sub2);
+                return slotId1 > slotId2 ? 0 : -1;
+            }
+        });
+
+        for (int subIdCounter = (subIdList.size() - 1); subIdCounter >= 0; subIdCounter--) {
+            int subId = subIdList.get(subIdCounter);
             if (subInfos == null || !containsSubId(subInfos, subId)) {
+                Log.d(LOG_TAG, "updatePhoneStateListeners: Hide the outstanding notifications.");
                 // Hide the outstanding notifications.
                 mApplication.notificationMgr.updateMwi(subId, false);
                 mApplication.notificationMgr.updateCfi(subId, false);
@@ -586,7 +604,16 @@
                 // Listening to LISTEN_NONE removes the listener.
                 mTelephonyManager.listen(
                         mPhoneStateListeners.get(subId), PhoneStateListener.LISTEN_NONE);
-                itr.remove();
+                mPhoneStateListeners.remove(subId);
+            } else {
+                Log.d(LOG_TAG, "updatePhoneStateListeners: update CF notifications.");
+
+                if (mCFIStatus.containsKey(subId)) {
+                    mApplication.notificationMgr.updateCfi(subId, mCFIStatus.get(subId));
+                }
+                if (mMWIStatus.containsKey(subId)) {
+                    mApplication.notificationMgr.updateMwi(subId, mMWIStatus.get(subId), isRefresh);
+                }
             }
         }
 
@@ -757,14 +784,16 @@
         @Override
         public void onMessageWaitingIndicatorChanged(boolean visible) {
             if (VDBG) log("onMessageWaitingIndicatorChanged(): " + this.mSubId + " " + visible);
-            mApplication.notificationMgr.updateMwi(this.mSubId, visible);
+            mMWIStatus.put(this.mSubId, visible);
+            updatePhoneStateListeners(false);
         }
 
         @Override
         public void onCallForwardingIndicatorChanged(boolean visible) {
             Log.i(LOG_TAG, "onCallForwardingIndicatorChanged(): subId=" + this.mSubId
                     + ", visible=" + (visible ? "Y" : "N"));
-            mApplication.notificationMgr.updateCfi(this.mSubId, visible);
+            mCFIStatus.put(this.mSubId, visible);
+            updatePhoneStateListeners(false);
         }
     };
 
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index eefa2c5..1764d4c 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -133,27 +133,6 @@
         mSubscriptionManager = SubscriptionManager.from(mContext);
         mTelecomManager = TelecomManager.from(mContext);
         mTelephonyManager = (TelephonyManager) app.getSystemService(Context.TELEPHONY_SERVICE);
-
-        mSubscriptionManager.addOnSubscriptionsChangedListener(
-                new OnSubscriptionsChangedListener() {
-                    @Override
-                    public void onSubscriptionsChanged() {
-                        updateActivePhonesMwi();
-                    }
-                });
-    }
-
-    public void updateActivePhonesMwi() {
-        List<SubscriptionInfo> subInfos = mSubscriptionManager.getActiveSubscriptionInfoList();
-
-        if (subInfos == null) {
-            return;
-        }
-
-        for (int i = 0; i < subInfos.size(); i++) {
-            int subId = subInfos.get(i).getSubscriptionId();
-            refreshMwi(subId);
-        }
     }
 
     /**
@@ -205,7 +184,7 @@
         if (mMwiVisible.containsKey(subId)) {
             boolean mwiVisible = mMwiVisible.get(subId);
             if (mwiVisible) {
-                updateMwi(subId, mwiVisible, true /* isRefresh */);
+                mApp.notifier.updatePhoneStateListeners(true);
             }
         }
     }
@@ -273,6 +252,10 @@
             }
 
             int resId = android.R.drawable.stat_notify_voicemail;
+            if (mTelephonyManager.getPhoneCount() > 1) {
+                resId = (phone.getPhoneId() == 0) ? R.drawable.stat_notify_voicemail_sub1
+                        : R.drawable.stat_notify_voicemail_sub2;
+            }
 
             // This Notification can get a lot fancier once we have more
             // information about the current voicemail messages.
@@ -493,14 +476,18 @@
             }
 
             String notificationTitle;
+            int resId = R.drawable.stat_sys_phone_call_forward;
             if (mTelephonyManager.getPhoneCount() > 1) {
+                int slotId = SubscriptionManager.getSlotIndex(subId);
+                resId = (slotId == 0) ? R.drawable.stat_sys_phone_call_forward_sub1
+                        : R.drawable.stat_sys_phone_call_forward_sub2;
                 notificationTitle = subInfo.getDisplayName().toString();
             } else {
                 notificationTitle = mContext.getString(R.string.labelCF);
             }
 
             Notification.Builder builder = new Notification.Builder(mContext)
-                    .setSmallIcon(R.drawable.stat_sys_phone_call_forward)
+                    .setSmallIcon(resId)
                     .setColor(subInfo.getIconTint())
                     .setContentTitle(notificationTitle)
                     .setContentText(mContext.getString(R.string.sum_cfu_enabled_indicator))
@@ -531,10 +518,17 @@
                         userHandle);
             }
         } else {
-            mNotificationManager.cancelAsUser(
-                    Integer.toString(subId) /* tag */,
-                    CALL_FORWARD_NOTIFICATION,
-                    UserHandle.ALL);
+            List<UserInfo> users = mUserManager.getUsers(true);
+            for (UserInfo user : users) {
+                if (user.isManagedProfile()) {
+                    continue;
+                }
+                UserHandle userHandle = user.getUserHandle();
+                mNotificationManager.cancelAsUser(
+                        Integer.toString(subId) /* tag */,
+                        CALL_FORWARD_NOTIFICATION,
+                        userHandle);
+            }
         }
     }