Eliminate the interfere of removeMessage for dual-SIM
In dual-SIM case, when two SIMs are loaded and try to fetch
CarrierConfig, one call of removeMessage(code) will remove
the timeout messages of both subscriptions.
This is fixed by sending timeout msg with phoneId as msg.obj
and calling removeMessage(code, obj) to only remove timeout
msg with the matching phoneId.
Bug: 181979320
Test: Manual smoke test
Change-Id: Ie7b20a4f609ce1eb8039753ce976d16510879923
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