Merge "Eliminate the interfere of removeMessage for dual-SIM"
diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index de41309..5196c59 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -281,7 +281,8 @@
                                 phoneId,
                                 EVENT_CONNECTED_TO_DEFAULT)) {
                             sendMessageDelayed(
-                                    obtainMessage(EVENT_BIND_DEFAULT_TIMEOUT, phoneId, -1),
+                                    obtainMessage(EVENT_BIND_DEFAULT_TIMEOUT, phoneId, -1 /*arg2*/,
+                                            getMessageToken(phoneId)),
                                     BIND_TIMEOUT_MILLIS);
                         } else {
                             // Put a stub bundle in place so that the rest of the logic continues
@@ -299,7 +300,7 @@
                 }
 
                 case EVENT_CONNECTED_TO_DEFAULT: {
-                    removeMessages(EVENT_BIND_DEFAULT_TIMEOUT);
+                    removeMessages(EVENT_BIND_DEFAULT_TIMEOUT, getMessageToken(phoneId));
                     final CarrierServiceConnection conn = (CarrierServiceConnection) msg.obj;
                     // If new service connection has been created, unbind.
                     if (mServiceConnection[phoneId] != conn || conn.service == null) {
@@ -318,7 +319,8 @@
                                         loge("Received response for stale request.");
                                         return;
                                     }
-                                    removeMessages(EVENT_FETCH_DEFAULT_TIMEOUT);
+                                    removeMessages(EVENT_FETCH_DEFAULT_TIMEOUT,
+                                            getMessageToken(phoneId));
                                     if (resultCode == RESULT_ERROR || resultData == null) {
                                         // On error, abort config fetching.
                                         loge("Failed to get carrier config");
@@ -350,7 +352,8 @@
                         break; // So we don't set a timeout.
                     }
                     sendMessageDelayed(
-                            obtainMessage(EVENT_FETCH_DEFAULT_TIMEOUT, phoneId, -1),
+                            obtainMessage(EVENT_FETCH_DEFAULT_TIMEOUT, phoneId, -1 /*arg2*/,
+                                    getMessageToken(phoneId)),
                             BIND_TIMEOUT_MILLIS);
                     break;
                 }
@@ -358,7 +361,7 @@
                 case EVENT_BIND_DEFAULT_TIMEOUT:
                 case EVENT_FETCH_DEFAULT_TIMEOUT: {
                     loge("Bind/fetch time out from " + mPlatformCarrierConfigPackage);
-                    removeMessages(EVENT_FETCH_DEFAULT_TIMEOUT);
+                    removeMessages(EVENT_FETCH_DEFAULT_TIMEOUT, getMessageToken(phoneId));
                     // If we attempted to bind to the app, but the service connection is null due to
                     // the race condition that clear config event happens before bind/fetch complete
                     // then config was cleared while we were waiting and we should not continue.
@@ -410,7 +413,8 @@
                         if (carrierPackageName != null && bindToConfigPackage(carrierPackageName,
                                 phoneId, EVENT_CONNECTED_TO_CARRIER)) {
                             sendMessageDelayed(
-                                    obtainMessage(EVENT_BIND_CARRIER_TIMEOUT, phoneId, -1),
+                                    obtainMessage(EVENT_BIND_CARRIER_TIMEOUT, phoneId, -1 /*arg2*/,
+                                            getMessageToken(phoneId)),
                                     BIND_TIMEOUT_MILLIS);
                         } else {
                             // Put a stub bundle in place so that the rest of the logic continues
@@ -426,7 +430,7 @@
                 }
 
                 case EVENT_CONNECTED_TO_CARRIER: {
-                    removeMessages(EVENT_BIND_CARRIER_TIMEOUT);
+                    removeMessages(EVENT_BIND_CARRIER_TIMEOUT, getMessageToken(phoneId));
                     final CarrierServiceConnection conn = (CarrierServiceConnection) msg.obj;
                     // If new service connection has been created, unbind.
                     if (mServiceConnection[phoneId] != conn || conn.service == null) {
@@ -445,7 +449,8 @@
                                         loge("Received response for stale request.");
                                         return;
                                     }
-                                    removeMessages(EVENT_FETCH_CARRIER_TIMEOUT);
+                                    removeMessages(EVENT_FETCH_CARRIER_TIMEOUT,
+                                            getMessageToken(phoneId));
                                     if (resultCode == RESULT_ERROR || resultData == null) {
                                         // On error, abort config fetching.
                                         loge("Failed to get carrier config from carrier app: "
@@ -478,7 +483,8 @@
                         break; // So we don't set a timeout.
                     }
                     sendMessageDelayed(
-                            obtainMessage(EVENT_FETCH_CARRIER_TIMEOUT, phoneId, -1),
+                            obtainMessage(EVENT_FETCH_CARRIER_TIMEOUT, phoneId, -1 /*arg2*/,
+                                    getMessageToken(phoneId)),
                             BIND_TIMEOUT_MILLIS);
                     break;
                 }
@@ -487,7 +493,7 @@
                 case EVENT_FETCH_CARRIER_TIMEOUT: {
                     loge("Bind/fetch from carrier app timeout, package="
                             + getCarrierPackageForPhoneId(phoneId));
-                    removeMessages(EVENT_FETCH_CARRIER_TIMEOUT);
+                    removeMessages(EVENT_FETCH_CARRIER_TIMEOUT, getMessageToken(phoneId));
                     // If we attempted to bind to the app, but the service connection is null due to
                     // the race condition that clear config event happens before bind/fetch complete
                     // then config was cleared while we were waiting and we should not continue.
@@ -1322,6 +1328,19 @@
     }
 
     /**
+     * Returns a boxed Integer object for phoneId, services as message token to distinguish messages
+     * with same code when calling {@link Handler#removeMessages(int, Object)}.
+     */
+    private Integer getMessageToken(int phoneId) {
+        if (phoneId < -128 || phoneId > 127) {
+            throw new IllegalArgumentException("phoneId should be in range [-128, 127], inclusive");
+        }
+        // Integer#valueOf guarantees the integers within [-128, 127] are cached and thus memory
+        // comparison (==) returns true for the same integer.
+        return Integer.valueOf(phoneId);
+    }
+
+    /**
      * If {@code args} contains {@link #DUMP_ARG_REQUESTING_PACKAGE} and a following package name,
      * we'll also call {@link IBinder#dump} on the default carrier service (if bound) and the
      * specified carrier service (if bound). Typically, this is done for connectivity bug reports