Fix incorrect android.telecom.Call.Details equality check.
The the android.telecom.Call.Details class provides its own equals
implementation. Recently added in M is to also check if the mExtras
and mIntentExtras are different. Unfortunately, Bundles do not implement
equals. As a result when Telecom calls are parceled and sent to the
InCallServices, this means that the internalUpdate method will always
assume that the Details of a call have changed, even if they have not.
This was causing a LOT of extra calls to onUpdate in the InCall UI (2x the
amount). Although there is still room for improvement in the number of
callbacks from Telecom, this fix prevents a pretty significant regression
on that front.
Bug: 23218195
Change-Id: I128e996faf60376ed3df1dc848a97c4a7b0482ee
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 4569549..0a1dbf6 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -512,8 +512,8 @@
Objects.equals(mGatewayInfo, d.mGatewayInfo) &&
Objects.equals(mVideoState, d.mVideoState) &&
Objects.equals(mStatusHints, d.mStatusHints) &&
- Objects.equals(mExtras, d.mExtras) &&
- Objects.equals(mIntentExtras, d.mIntentExtras);
+ areBundlesEqual(mExtras, d.mExtras) &&
+ areBundlesEqual(mIntentExtras, d.mIntentExtras);
}
return false;
}
@@ -1245,4 +1245,32 @@
});
}
}
+
+ /**
+ * Determines if two bundles are equal.
+ *
+ * @param bundle The original bundle.
+ * @param newBundle The bundle to compare with.
+ * @retrun {@code true} if the bundles are equal, {@code false} otherwise.
+ */
+ private static boolean areBundlesEqual(Bundle bundle, Bundle newBundle) {
+ if (bundle == null || newBundle == null) {
+ return bundle == newBundle;
+ }
+
+ if (bundle.size() != newBundle.size()) {
+ return false;
+ }
+
+ for(String key : bundle.keySet()) {
+ if (key != null) {
+ final Object value = bundle.get(key);
+ final Object newValue = newBundle.get(key);
+ if (!Objects.equals(value, newValue)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
}